Search code examples
reactjsredux-sagareact-admin

Not getting ID (it's undefined) of created record in redux-saga in React-admin


This is the problem. I wanted to catch ID of newly created record so I created custom watcher saga that listens to every "RA/CRUD_CREATE_SUCCESS". And my worker saga needs to get ID of newly created record so I can do second call to other endpoint using that ID, with some other data.

But for some reason every time the record is created, watcher saga does indeed work, but the ID of that record is undefined in payload. Everything else is there except the ID.

I am using simple form, and creating record just like they explain in documentation. I am using react-admin ver. 2.9.7

Any suggestions, ideas, fixes are welcome.


Solution

  • According to source, both on 2.9.7,

    https://github.com/marmelab/react-admin/blob/v2.9.7/packages/ra-core/src/actions/dataActions/crudCreate.ts#L86

    and

    https://github.com/marmelab/react-admin/blob/v2.9.7/packages/ra-core/src/types.ts#L7

    The id should be there, on action.payload.id. Since it's not, either is a react-admin bug, which you can try changing the version to fix, or your dataProvider not returning the id of created resources, but with that, react-admin probably would complain and you would have already noticied the error, and after creating, if redirect="edit", you would be redirect to /resource/undefined. This happen?

    If this a ra bug, you can try to extract id from action.meta.redirectTo, if it's there, or, not using sagas at all, intercept dataProvider requests, and everytime a CREATE request succeds, do your second call:

    import { CREATE } from 'react-admin'
    
    const interceptorDataProvider = dataProvider = async (verb, resource, params) => {
         if (verb === CREATE) {
    
             let response
    
             try {
                 response = await dataProvider(verb, resource, params)
             } catch (e) {
                 return Promise.reject(e)//ra expects rejecteds promises
             }
    
             //do your second call with response.data.id
             return response             
    
         }
    
        return dataProvider(verb, resource, params)
    }