question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Data Provider 'update' function: params.data has updated ID but also carries old body JSON fields

See original GitHub issue

What you were expecting:

I have two resources Article and Author and an Article can have one single Author field with name author.

My expectation is that when I change the value of the author field in an Article during Edit, the submission of an Article update should trigger a call to my data provider’s update function passing in a JSON of Article that simply updates the ID of the nested author field, i.e. something that looks like:

{
   "id":2,
   "title":"Some Title",
   "url":"https://some.url.com",
   "imageUrl":"https://some.image.url.com",
   "visible":true,
   "startVisible":"2019-09-29T11:11:00Z",
   "endVisible":"2019-10-29T07:02:00Z",
   "author":{
      "id":6
   }
}

What happened instead:

Contrary to my expectation, when I change the value of the author field in an Article during Edit, the submission of an Article update actually triggered a call to my data provider’s update function passing in a JSON of Article that embeds the complete JSON of the nested author field, i.e. something that looks like:

{
   "id":2,
   "title":"Some Title",
   "url":"https://some.url.com",
   "imageUrl":"https://some.image.url.com",
   "visible":true,
   "startVisible":"2019-09-29T11:11:00Z",
   "endVisible":"2019-10-29T07:02:00Z",
   "author":{
      "id":6,
      "blogSubTitle":"Old Blog Subtitle",
      "blogTitle":"Old Blog Title",
      "name":"Old Author Name1",
      "introduction":"Old Intro",
      "imageUrl":"https://old.image.url.com"
   }
}

Steps to reproduce:

In my Edit for Article I have:

export const ArticleEdit = props => (
    <Edit {...props}>
        <TabbedForm>
            <FormTab label="summary">
                <TextInput disabled source="id"/>
                <TextInput source="title" />
                <TextInput source="url" />
                <TextInput source="imageUrl" />
                <ReferenceInput source="author.id" reference="author" label="resources.feed/article.fields.author">
                    <SelectInput optionText="name" />
                </ReferenceInput>
            </FormTab>
            <FormTab label="campaign">
                <DateInput source="startVisible" parse={dateParser}/>
                <DateInput source="endVisible" parse={dateParser}/>
                <BooleanInput source="visible"/>
            </FormTab>
        </TabbedForm>
    </Edit>
);

At first glance, everything seems fine in that when I load the Article Edit page, I see the right REST API Data Provider functions (getList and getMany) get called for Author and thereafter the proper value show up for the author field, using the nameattribute ofAuthor`.

And when I choose a different Author in the drop down, the right REST API Data Provider calls get made for getMany too.

But when I click on the SAVE button, and having printed out the the params.data in my custom data provider, I see an unexpected JSON body as mentioned above.

Other information:

Environment

  • React-admin version: 3.5.3
  • Last version that did not exhibit the issue (if applicable):
  • React version: 16.13.1
  • Browser: Chrome / Edge
  • Stack trace (in case of a JS error):

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
paulito415commented, May 27, 2020

Thanks @fzaninotto for your comment. I understand and agree with your position with respect to keeping the centralized local store as a reason to keep these performance improvements and optimistic rendering. In fact, I was not actually suggesting that this store be removed though. My point was that even though I can do some pre-processing in my dataProvider’s update() implementation for article, as you correctly pointed out, it would not be architecturally as elegant because I would need to do this not only for articles / authors but also other entities down the road that may have such an embedding relationship.

It boils down to whether we see this pre-processing as generic enough to generalize in my dataProvider’s update method (for all my entities), or more generic than that to push this into the react-admin pre-processing. I guess the answer is that it’s generic enough to put in my dataProvider but not generic enough to put in the calling code of react-admin.

I understand and appreciate that decision and know that I might have some more work cut out for me to make this work. But since I have control over my Grails REST controller I can devise something on that end to reduce work on the react-admin usage end. What I actually ended up deciding was to introduce a URL parameter that makes it render shallow objects like the way react-admin expects and in my dataProvider’s getOne call, I post-pend my URL with this URL parameter. Not the most elegant either but beats having to process JSON in JS code and remove select fields before updating.

Thanks again for looking into this and for the explanation on the local store.

0reactions
fzaninottocommented, May 27, 2020

React-admin keeps a local store of all the records your app has requested. These records are shared between views, and requests. So yes, if the getOne() call returned an embedded record, the update() record will contain it, to.

That’s a design choice, and that’s what allows us to provide significant performance improvements and optimistic rendering. This centralized store cannot be disabled.

In your case, you probably need to tweak the update() method in your dataProvider to remove the embedded record if the resource is article.

Anyway, as this is not a react-admin bug, I’m closing the issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Extend JSON Server Data Provider in React-Admin so the ...
When updating (PUT) my backend do not accept the ID in the body (the reference for the id is in the url: http://api.com/item/{id})....
Read more >
Best practices for REST API design - Stack Overflow Blog
Learn how to design REST APIs to be easy to understand for anyone, future-proof, secure, and fast since they serve data to clients...
Read more >
Web API implementation - Best practices for cloud applications
Learn about best practices for implementing a web API and publishing it to make it available to client applications.
Read more >
A comprehensive guide to data fetching in React
We'll demonstrate how to fetch data in React, complete with code examples, and introduce a handful of approaches to help you determine the...
Read more >
Modifying JSON data using JSON_MODIFY() in SQL Server
Example 1: Update JSON property value · First argument expression contains original JSON {“Brand”:”HP”,”Product”:”Laptop”} · $.Product is the ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found