Using React & Redux & Redux-Thunk, trying to make this pseudocode:
// pseudocode
dispatch(makeServiceRequest)
if failed
dispatch(makeIdentityRequest)
if successful
dispatch(makeServiceRequest)
end
end
Want to avoid an infinite loop which would happen if the code was placed inside the .catch block of makeServiceRequest.
I'm using a fetch(url).then(...).catch(...) logic in the dispatch action. fetch does not reject on HTTP status errors.
How do I make this pseudocode happen? What is the correct pattern to handle a situation like this?
Just have a then that checks HTTP status and throws an error if it isn't a success status just like it says in your link:
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
var error = new Error(response.statusText)
error.response = response
throw error
}
}
fetch(url).then(checkStatus).then(...).catch(...);
Other than that, I'm not clear on what your Redux-specific question is.
Edit: based on your comments, I think you are asking how to manage a Redux actions that, when dispatched, can asynchronously dispatch other actions. One way to model that is as a "saga". There's a Redux library called redux-saga that lets you model this sort of thing.
Related
I am currently working on a project that requires using rtk query. Is there a way to get unwrapped value by default for mutations.
const [removeStudent] = useRemoveStudentMutation()
and i have the call for removeStudent() within try catch because removeStudent can fail in which case i show an error message. Something like this.
try{
await removeStudent().unwrap()
// logic for showing success message
}
catch(e){
//logic for showing error message
}
problem is if i don't use unwarp i'm getting a success message even when the removeStudent() failed. Is there a way i could make unwrap() apply to all mutations.So that i don't have to use unwrap every time i write a mutation.Maybe at createApi level
Thanks
When I am working with API call from my front end APP for example ReactJS I am always using a store, I love redux-saga, the good practice with saga is to call your API strictly in your effect handler, it will looks like this:
function mySaga*(){
yield put(loadingRequest);
try{
const response = yield call(axios.get, "https://*******.com");
yield put(saveResponseSomewhereInMyStore(response)
yield put(requestSuccess())
} catch(err){
yield put(requestFailure(err)
}
}
then my store State look like this
interface StoreState{
data:{....};
request:{
login:{
status:"LOADING" | "SUCCESS" | "FAILURE" | "NOT_FIRED",
error:HttpErrorResponse | null
}
}
}
With this approach I have to make a requestStatusSelector and use the hook useSelector every time I need to react to this status inside the view.
Is it the best strategy? For more complex situations I have to useEffect on this selector to trigger an other dispatch, for me it seems little bit dirty.
What are your strategies to handle API response status and error?
So I have redux-thunk set up and when I call the updateUser(userInfos) action, it returns a promise to update the server with those infos.
But sequentially I need to update the local state with those infos too, and if I wait for UPDATE_USER_FULFILLED, the effect of my action is not instantaneous, which feels weird for the user.
I thought of reducing the UPDATE_USER_PENDING action to update the local state before the server response arrives with up-to-date data (which should be the same so no re-rendering), but unfortunately, the payload of UPDATE_USER_PENDING action is null :(
Ain't there a way to load it with some data, which would allow instant UI response before server return?
Could be something like:
export function updateUser(user) {
return {
type: UPDATE_USER,
payload: {
promise: userServices.update(user),
localPayload: user,
}
}
}
but I'm guessing this is not available?
For now, the only solution I see is to create a UPDATE_USER_LOCAL action which would do the local action in parallel with the server call. But this is not very elegant and much heavier.
Thanks for the help
Firebase spits out an error if a request takes too long to resolve due to slow internet connections. Here is the error:
#firebase/firestore: Firestore (7.9.2): Could not reach Cloud Firestore backend. Connection failed 1 times. Most recent error: FirebaseError: [code=unavailable]: The operation could not be completed
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.
I ran into an odd behaviour with redux-thunks when trying to catch this error. My api function was able to catch the firebase error in its catch() block but was not caught in the catch() block within the thunk action. Here is some pseudocode to illustrate this better:
api.js
getDoc () {
return firebase.firestore().doc().get().then(result => {
return result
}).catch(error => {
//error caught here
console.log(error)
})
}
thunks.js
action () {
api.getDoc().then(result => {
//result contains the error
dispatch(success(result));
})
.catch(error => {
//not being reached
dispatch(failed(error))
})
}
I created a code sandbox to reproduce the error. Feel free to play around with the code. When you go offline while the app is fetching data, the firebase error will get thrown, and the console will show that the backend api caught the error but the thunk action failed to do so.
I am not certain if this is an error on my part or a limitation of the redux-thunk library or firebase library.
Question: How can I handle this error so my thunk action does not dispatch an error as a success?
Any help will be warmly welcomed.
That message is just a notice to you. It's not really an error, and you can't catch it. Firestore doesn't treat networks problems as errors. It just continually retries in the background.
Here is a solution in the event anyone comes across this error.
The simplest solution is to remove the catch() block from the api function and catch errors at the caller function. Based on the example code provided in the question, the only modification would be to the api.js file:
getDoc () {
return firebase.firestore().doc().get().then(result => {
return result
})
}
While testing, if the error gets thrown by firebase, the thunk's catch() block is hit which dispatches the error action.
I’m trying to implement authentication in my angularjs app.
I’ve read some articles about doing this properly. Here is one, for instance: https://medium.com/opinionated-angularjs/techniques-for-authentication-in-angularjs-applications-7bbf0346acec
But I can’t realize how to make it respond on wrong username/password pair.
Let’s have a look at this code :
authService.login = function (credentials) {
return $http
.post('/login', credentials)
.then(function (res) {
// populate user info
}
);
};
I’ve tried to add here a second callback to “then” method and use “success”/”error” methods instead of “then” and I’ve tried to response on $http.post request with different error like 400 and 500 via status, but in any case all the errors are handled by the success method and callback.
What am I doing wrong? How to catch wrong password/username response in angular?
It was actually my own fault. My custom Intereptor simply swallowed authenticaion errors.