Concurrent call on CRUD endpoint issue
Hi,
I'm not sure I can quickly create reproducible example, but here is the case.
I have an endpoint defined:
registrations: { url: `/api/registrations`, crud: true, transformer: transformers.array },
In one place I'm using get() to get the data:
console.log("Getting data...");
dispatch(rest.actions.registrations.get({}, {}, (err, data) => {
console.log("SETTING STATE", data);
this.setState({
registrations: data
})
}));
(the original code was simpler, I was simply using props.registration.data, but then, investigating this issue, created this)
In another place (modal window) I do POST request for this endpoint:
this.props.dispatch(rest.actions.registrations.post({}, { body: JSON.stringify(data) }, (err, data) => {
if (err != null) {
console.log("Call failed: ", err);
this.setState({ error: err.message });
return
}
}))
So, when POST request happens, data for the first GET request is also changed. In fact I see in console log this:
Getting data...
SETTING STATE > [Object] // which is valid data obtained with GET request
// ... modal window appears and sends POST request ...
SETTING STATE > [Object] // with object equal to result of POST: { status: "success" }
Note, that after POST request there is no "Getting data..." log entry. It looks like callback from the first action dispatch got called automagically by itself after POST request.
Any idea what I'm doing wrong here?
Hello @divan you can't update state concurrently. In you case post request return poor json response like { status: "success" } but for redux-api it's new state. You should return new state of object with post request or write custom transformer, that doesn't rewrite state.
I am encountering this issue as well. What is the correct way to handle this case?
One component that pulls rest data for individual records using the crud helpers. For example addresses. You need to display an origin and destination, but the api endpoint is the same. How can I hook in to use the redux-api concept? Right now, both addresses show the same data even though they fetch different ids from the remote server
address: {
url: '/addresses/address/:pk/?format=json',
virtual: true,
crud: true
},
getData = () => {
const obj = this
if (this.needData()) {
if (this.canGetData()) {
const params = parse_endpoint_url(this.url, endpoints.address)
const action = rest.actions.address.get(params, {}, (error, data)=> {
error = error || {}
data = data || {}
obj.setState({
data, error
})
});
this.props.dispatch(action);
} else {
this.setState({
error: {statusText: 'Unable to get data.'}
})
}
}
}
Is it possible to keep a cached array of the last X responses? Then in select state the address can be picked by ID or refetched?
for now directly using request works but doesn't give a way to update on change
getData = () => {
const obj = this
const done = (data, error) => {
obj.setState({
data, error
})
}
if (this.needData()) {
if (this.canGetData()) {
const params = parse_endpoint_url(this.url, endpoints.address)
rest.actions.address.request(params).then((data)=> {
done(data, {})
}, (error) => {
done({}, error)
});
} else {
done({}, {
error: {statusText: 'Unable to get data.'}
})
}
}
}