export function postRegister(credentials) {
console.log(credentials);
return dispatch => {
return fetch('/user/register', {
method: 'post',
body: JSON.stringify(credentials),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
}
}
I have few doubts regarding code above.
Can I use export () => {} instead of writing the word function here? Just to stay cleaner.
dispatch is a global variable? I did not see it's imported or required somewhere in the file.
Is specifying headers necessary here? I'm seeing that in every of the api call.
Why there's no catch in this promise call? Overall the code is bad?
No really, you could but you need a name to actually use it in your components.
No, dispatch is a parameter of the arrow function, you can also define getState to access the current redux state. By the way, you can totally assign new names if you want.
It depends on your server, but generally if you are using a JSON API, you would want to send that header.
Yes, overall that code doesn't look good, I would recommend using a middleware to handle the fetch requests, your actions should only send the configurations such as the url, body, method, etc... and your middleware should handle adding common headers (such as the content-type).
You could have an action like this:
export function postRegister(credentials) {
return {
types: [REGISTER, REGISTER_SUCCESS, REGISTER_FAIL],
promise: {
url: '/user/register',
data: credentials,
},
};
}
Something as simple as that, then your middleware should do the fetch and dispatch the action types based on the server response.
If you want to know more about how the middleware should handle the fetch request and dispatch the actions, make sure to take a look at my post here: https://stackoverflow.com/a/39971763/146718
not unless it is export default. since later u will need to import it by name.
no, dispatch is an argument that is passed to your function:
(dispatch) => {}
Totally depends on your application, server, request, etc.
you could add .catch((e) => {}) your self, or use some interceptors for generic errors, do a dipatch from there and add a reducer which will handle these actions. you could read more here:
What is the best way to deal with a fetch error in react redux?
Related
Problem
I am currently working on UI and I use React. Inside of the .jsx component, I have everything : HTML (JSX), JavaScript-Logic, and API calls. Everything in one file, this gets messy.
Goal
I would like to outsource functionality, so I created a class that should handle all API-Calls. I also would like to use RxJS and combine axios with RxJs.
Code
What is happening in the the code? I have a class ApiCalls that contains a static method putApiCallExample. There I do the api call but creating a Promise with axios. I use the from() functionality form rxjs to create an observable and inside the pipe i return the data.
In the Main.jsx I am using this in the useEffect()-hook, I subscribe on it and set the State based on it.
class ApiCalls:
static putApiCallExample(URL, data){
const promise = axios
.put(URL, data, {
headers: {
"Content-Type": "application/json"
}
});
return from(promise).pipe(map(res => res.data));
}
const Main = () => {
const [show, setShow] = useState(false);
useEffect(() => {
ApiCalls.putApiCallExample().subscribe(
res => {
console.log("1", res);
setShow(true);
},
err => {
console.log("2", err)
}
);
}, [])
}
Question
Can I interpet the subscribe() functionality as same as .then() from axios ?
Do I need to unsubscribe here?
Does this cause performance issues to mix axios and rxjs?
I assume that if you use Axios, you don't need to receive multiple response from the server like for SSE or websocket. So:
Can I interpet the subscribe() functionality as same as .then() from axios ?
In a way, yes, the observable subscribe callback is triggered when Axios promise resolves. Then it will not be triggered anymore, so in this specific case, the RxJs observable behaves the same way as the Axios promise.
Do I need to unsubscribe here?
As the Observable can't be triggered more than 1 time, I don't see any reason to unsubscribe.
Does this cause performance issues to mix axios and rxjs?
You're only wrap Axios promise into a RxJs observable. This RxJs wrapper will not have a significant memory or CPU blueprint.
By the way, this is basically what's Angular Http client is doing internally. My opinion is that it's safe, but it doesn't bring too much value either.
I am new in vue js . I want to call api . it is perfectly working. but i want to put condition on that if api response is this than vue js array is updated .
this is my code . but it gives me error "do not mutate vuex store state outside mutation handlers."
How to handle this?
axios.post(baseUrl+'/api/v1/addProductWishlist',pitem,
{headers: {
'Authorization': 'Bearer ' + x,
'Content-Type':'application/json'
}
}).then(r => {
if(r.data.status == 202)
{
}
else{
state.cartItems.push(payload);
}
});
use Mutation to modify state, do not redirect change state instance
for more detail: https://vuex.vuejs.org/guide/mutations.html
Notice that you don't follow the correct pattern of using Vuex.
You should update the state ONLY from within a mutation. It is an important part in state management in Vuex (as well as in other frameworks). Not following this concept might break the reactivity Vuex maintains and make a big app extremely unpredictable since you can't follow which part of the app have changed a value in your state.
A good practice would be to separate mutations, actions and api calls to 3 different files. The action might be your functionality manager - create an action that calls the api file function (that only executes the axios api call), and after getting back the response calling the mutation from the mutations file to update the state accordingly.
// actions.js
{
myAction: async ({ commit }) => {
const response = await myApiCall();
if (response.data.status == 202) { ... }
else {
commit('ADD_CART_ITEM', response.item)
}
}
}
// api.js
export function myApiCall() {
return axios.post(...)
}
// mutations.js
{
ADD_CART_ITEM: (state, payload) => state.cartItems.push(payload);
}
I have 2 modules in Nest.js let's call them Module1 and Module2. Module1 has an endpoint of /api/module1 and Module2 has /api/module2. I am trying to call Module2 from Module1 as below
return await this.httpService
.post(url, data1, {
headers: header
})
.pipe(
map(res => {
return res.data;
}),
);
Here the url is /api/module2 and data1 is the parameter i'm passing. When I make the call, this is what I see
{"_isScalar":false,"source":{"_isScalar":false},"operator":{}}
I usually see this error when a promise is returned before it's fully done. Not sure what to do differently here. The method which is holding this httpService called is enclosed inside an async and the calling method has an await as well.
What you're seeing there is a raw observable that hasn't been subscribed to, probably due to returning a promise instead of returning the observable. Nest's HttpService uses RxJS instead of async/await by default, but to fix this you can easily add a .toPromise() after the RxJS object and not worry about the subscription yourself.
As a side note: any reason to call the API via the HTTP module and not just call the service with the proper values directly? Seems like a lot of overhead for a REST call.
I was working with redux-thunk and superagent npm for jwt authentication and i would want to know how to implement post calls using thunk-middleware in the actions.js file and not in the main reducer.js file
There's a couple of different ways to go about it, but I personally like to use the axios library. Axios essentially just assists with making an API request and parsing the data back from the API into json.
In your actions.js file.
export const authenticateUser = () => {
return (dispatch, getState) => {
//get the token from the reducer
const jwtToken = getState().jwtTokenReducer.tokenKey
axios.post("/api/authenticate-user", jwtToken) //jwtToken passed into request
.then((res) =>){
dispatch({
type: "AUTHENTICATE_USER",
payload: res.data
})
}
.catch((errors) => {
dispatch({
type: "ERRORS",
payload: errors.response.data
})
})
}
}
So take a look at the above syntax. Typically when you define an action-creator, you setup a function that returns an action (object). But thanks to redux-thunk, you can now setup your action-creators to return functions with dispatch as an argument.
So in your returned function you can define certain logic, like making a request to an API like we did up there. Then we can take that data by using the .then promise handler and use it as a payload for an action that we would explicitly dispatch to our reducers.
I have a JS design question about how to provide a redux store to files that aren't react components. I have a typical react-redux application. Instead of calling fetch directly from my react components, I currently make all of my service calls in a centralized simple functional utility method file called fetches.js.
const mainFetch(uri, onSuccess, options) {
fetch(uri, options).then(response => {
onSuccess(response);
});
}
const export fetchDogs = (onSuccess) => {
mainFetch('/dogs', onSuccess, { method: 'GET' });
}
const export fetchCats = (onSuccess) => {
mainFetch('/cats', onSuccess, { method: 'GET' });
}
I realized that it'd be useful for my application to know exactly which of these requests we're currently waiting for. So I was thinking of adding this information to my redux state so that I could update mainFetch to look something like:
const mainFetch(uri, onSuccess, options, requestId) {
store.dispatch({type: 'STARTED_REQUEST', request: requestId);
fetch(uri, options).then(response => {
store.dispatch({type: 'FINISHED_REQUEST', request: requestId);
onSuccess(response);
});
}
But there's one problem, fetches.js has no access to the redux store. I could add a 'store' param to all of the methods in fetches.js, however I was thinking there'd be a better JS design pattern. Maybe initializing a class in App.js or something, similarly to how react-redux uses the Provider and 'connect' to provide the store to all child components. I'm new to JS so I was wondering how an experienced JS developer would solve this problem.
This design is lacking a middleware to handle the promises.
The basic idea is when you dispatch a Promise, from the code where you are 'calling' these 'fetch' functions, there would be a middle ware which would take the action dispatched and dispatch other actions such as 'Started fetching' and 'fetching ended' to mark the asynchronous flow.
A good start would be this link on the official site of redux - https://redux.js.org/advanced/asyncflow
A middleware - https://github.com/pburtchaell/redux-promise-middleware