How to fetch multi data in useEffect - javascript

in my react application i want to use multi fetch in useEffect but, they not working just first function works!.
code:
useEffect(() => {
const getInfo = async () => {
try {
const user = await transitionData(
`http://localhost:5000/user/${authContext.userId}/profile?t=user`,
"GET",
null,
{ Authorization: `Bearer ${authContext.token}` }
);
const posts = await transitionData(
`http://localhost:5000/user/${authContext.userId}/profile?t=posts`,
"GET",
null,
{ Authorization: `Bearer ${authContext.token}` }
);
const savedPosts = await transitionData(
`http://localhost:5000/user/${authContext.userId}/profile?t=saved`,
"GET",
null,
{ Authorization: `Bearer ${authContext.token}` }
);
setUser(user);
setPosts(posts);
setSaved(savedPosts);
} catch (error) {}
};
getInfo();
}, [transitionData, authContext.userId, authContext.token]);

Related

what could be going wrong in this fetch?

I tried this solution to fetch data from multiple apis with async await but the output is undefined, what could be going wrong?
const getData = async (jwt) => {
try {
const [response1, response2, response3] = await Promise.all(
[
fetch("http://localhost:3000/api/confirmed"),
fetch("http://localhost:3000/api/deaths"),
fetch("http://localhost:3000/api/recovered"),
],
{
method: "GET",
headers: {
"user-agent": "vscode-restclient",
"content-type": "application/json",
accept: "application/json",
authorization:
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IkxlYW5uZSBHcmFoYW0iLCJ1c2VybmFtZSI6IkJyZXQiLCJpYXQiOjE1OTY1MDY4OTN9.KDSlP9ALDLvyy0Jfz52x8NePUejWOV_mZS6cq4-JZXs",
},
}
);
const { data1 } = await response1.json();
const { data2 } = await response2.json();
const { data3 } = await response3.json();
console.log(data1, data2, data3);
} catch (err) {
console.error(`Error: ${err}`);
}
};
getData();
Promise.all only accepts a single parameter, an array of promises. Your second parameter (the object with method and headers) is therefore simply ignored. That obect needs to be passed as a second parameter to the fetch function, not to Promise.all.
Try the following:
const getData = async (jwt) => {
try {
const fetchOptions = {
method: "GET",
headers: {
"user-agent": "vscode-restclient",
"content-type": "application/json",
accept: "application/json",
authorization:
"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtZSI6IkxlYW5uZSBHcmFoYW0iLCJ1c2VybmFtZSI6IkJyZXQiLCJpYXQiOjE1OTY1MDY4OTN9.KDSlP9ALDLvyy0Jfz52x8NePUejWOV_mZS6cq4-JZXs",
},
};
const [response1, response2, response3] = await Promise.all(
[
fetch("http://localhost:3000/api/confirmed", fetchOptions),
fetch("http://localhost:3000/api/deaths", fetchOptions),
fetch("http://localhost:3000/api/recovered", fetchOptions),
],
);
const { data1 } = await response1.json();
const { data2 } = await response2.json();
const { data3 } = await response3.json();
console.log(data1, data2, data3);
} catch (err) {
console.error(`Error: ${err}`);
}
};
getData();

How do I return an item from an async funtion

Ive been looking into trying to get information from websites using fetch. Trying async/await was my first solution, and so far it has been going well. Getting the information I needed was a breeze, but trying to retrieve that data in main is my problem. Const data in my main function even with the await tag only returns an undefined object. How can I get the data that I have in the function into my main
import React from "react";
import {
WASTEMANAGEMENT_USERNAME,
WASTEMANAGEMENT_PASSWORD,
WASTEMANAGEMENT_APIKEY_AUTH,
WASTEMANAGEMENT_APIKEY_CUSTID,
WASTEMANAGEMENT_APIKEY_DATA,
} from "#env";
async function login() {
let response = await fetch("https://rest-api.wm.com/user/authenticate", {
method: "POST",
headers: {
"content-type": "application/json",
apikey: WASTEMANAGEMENT_APIKEY_AUTH,
},
body: JSON.stringify({
username: WASTEMANAGEMENT_USERNAME,
password: WASTEMANAGEMENT_PASSWORD,
locale: "en_US",
}),
});
let res = await response.json();
const id = res.data.id;
const access_token = res.data.access_token;
response = await fetch(
`https://rest-api.wm.com/authorize/user/${id}/accounts?lang=en_US`,
{
method: "GET",
headers: {
oktatoken: access_token,
apikey: WASTEMANAGEMENT_APIKEY_CUSTID,
},
}
);
res = await response.json();
const custId = res.data.linkedAccounts[0].custAccountId;
response = await fetch(
`https://rest-api.wm.com/account/${custId}/invoice?userId=${id}`,
{
method: "GET",
headers: {
apikey: WASTEMANAGEMENT_APIKEY_DATA,
token: access_token,
},
}
);
res = await response.json();
res.body.balances.filter((item) => {
if (item.type === "Current") {
console.log(item);
return item;
}
});
}
const WasteManagementLogin = async () => {
const data = await login();
console.log(data);
};
export default WasteManagementLogin;

React : call async method from same file

I am trying to call removeCouponCode method which exist in same file but execution says its not defined i am not sure what is missing here.
any thoughts ?
Below is the file which i am editing & trying to make changes.
not sure what is missing.
please have a look at let me know what is missing
import React, { useState, useEffect, useMemo } from 'react';
import SessionContext from 'react-storefront/session/SessionContext';
import PropTypes from 'prop-types';
import fetch from 'react-storefront/fetch';
import get from 'lodash/get';
import { EventTracking, AnalyticsErrors } from '../analytics/Events';
import Cookies from 'js-cookie';
import constants from '../constants/configs';
import errorHandler from '../constants/apiHelpers/errorHandler';
import Helper from '../constants/helper';
import configs from '../constants/configs';
const { session, actions } = useContext(SessionContext);
const initialState = {
signedIn: false,
cart: {
items: [],
shipping_methods: [],
shippingCountry: null,
shippingMethodCode: null,
freeShipingMethod: null,
freeShippingSelected: false
},
customer: {
store_credit: {},
wishlist: { items_count: 0, items: [] },
offline: true
},
errMsg: ''
};
const initialStatusState = {
cartLoadingStatus: false,
setShippingMethodStatus: false
};
async redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
async removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
You didn’t reference your function and reference your function and try or you can either modify your code as follows by declaring it as a function,
async function removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
}
async function redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
await removeCouponCode(...otherParams);
}
}
}
You did not declare them as function. So you define them either this way
async function redemptionCode({ couponCode, ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
async function removeCouponCode({ ...otherParams }) {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
Or this way
const redemptionCode = async ({ couponCode, ...otherParams }) => {
let tempSession = { ...session };
const response = await fetch('/api/cart/redemptionCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ couponCode, ...otherParams })
});
const result = await response.json();
if (response.ok) {
if(get(result, 'cart.prices.discounts', {}) === null){
removeCouponCode(...otherParams); //says undefined removeCouponCode here
}
}
},
const removeCouponCode = async ({ ...otherParams }) => {
let tempSession = { ...session };
const response = await fetch('/api/cart/removeCouponCode', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...otherParams })
});
},
Both should work!
It seems that you define this function after calling it. I think you should first define it and then call it..and you can use the arrow function.

NextJS: TypeError: Cannot read property 'json' of undefined

I've this code into pages folder on my NextJS environment. It gets data calling an external API Rest, and it's working because the console.log(response); line show me by console the Json API response. The problem I've is that I get this error in browser:
TypeError: Cannot read property 'json' of undefined
Corresponding with this line code:
const data = await res.json();
This is the complete file with the code:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data Json: ", data);
return { props: { data } };
};
This is the Json API response that I see by console:
{
account: [
{
id: '7051321',
type: 'probe',
status: 'open',
newAccount: [Object],
lastDate: '2020-07-04',
taxExcluded: [Object],
totalRecover: [Object],
documentLinks: []
},
]
}
Any idea how can I solve it?
Thanks in advance.
UPDATE
Here the code working good:
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try {
const res = await getFetch(invoicesUrl, params);
const data = await res.json();
console.log("Data JSON: ", data);
return { props: { data } };
} catch (error) {
console.log("Data ERROR: ", error);
}
};
There are a couple of things you have to change.
const getFetch = async (invoicesUrl, params) => {
fetch(invoicesUrl, params)
.then((response) => {
return response.json();
})
.then((response) => {
console.log(response);
return response; // 1. Add this line. You need to return the response.
})
.catch((err) => {
console.log(err);
});
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
const data = await getFetch(invoicesUrl, params);
// const data = await res.json(); 2. Remove this you have already converted to JSON by calling .json in getFetch
console.log("Data Json: ", data); // Make sure this prints the data.
return { props: { data } };
};
You have return statement in wrong place.
When the function is expecting a return. You need to return when the statements are executed not inside the promise then function because it is an async callback function which is not sync with the statement inside getFetchfunction. I hope i have made things clear. Below is the code which will any how return something
import React from "react";
import fetch from "node-fetch";
const getFetch = async (invoicesUrl, params) => {
return fetch(invoicesUrl, params);
};
export const getServerSideProps = async () => {
const invoicesUrl = "https://192.168.1.38/accounts/123456";
const params = {
method: "get",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
};
try{
const res = await getFetch(invoicesUrl, params);
console.log("Data Json: ", res);
}catch(error){
console.log("Data Json: ", error);
}
return { props: { res } };
};

React useState hook not working as I would expect

I'm using the useState hook in React and it's behaving in an odd way.
If you look at the example below here is what I would expect: call login, on success it calls setRefreshToken(responseToken) then calls refresh() which references refreshToken set from setRefreshToken. What actually happens is refreshToken is undefined inside of refresh().
I know setState is async but I haven't run in to issues like this before. Am I missing something?
import React, { createContext, useState } from "react";
import jwtDecode from "jwt-decode";
const localStorageKey = "ar_refresh_token";
export const AuthContext = createContext();
export function AuthProvider({ tokenUrl, registerUrl, refreshUrl, children }) {
const [refreshToken, setRefreshToken] = useState(
window.localStorage.getItem(localStorageKey)
);
const [accessToken, setAccessToken] = useState();
const login = async (userId, password) => {
const response = await fetch(tokenUrl, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
userId,
password
})
});
if (response.status === 201) {
const token = await response.text();
setRefreshToken(token);
window.localStorage.setItem(localStorageKey, token);
await refresh();
}
};
const refresh = async () => {
const response = await fetch(refreshUrl, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
Authorization: `JWT ${refreshToken}`
}
});
if (response.status === 201) {
const token = await response.text();
setAccessToken(token);
}
};
return (
<AuthContext.Provider
value={{
refreshToken,
accessToken,
login,
refresh
}}
>
{children}
</AuthContext.Provider>
);
}
Full example: https://github.com/analyticsrequired/auth-admin/blob/master/src/AuthContext.js
You are right in that the component will not have been re-rendered before you call refresh, so the refreshToken inside refresh will be the default one.
You could instead pass in the token from login as an argument to refresh and use that and it will work as expected.
const login = async (userId, password) => {
// ...
if (response.status === 201) {
// ...
await refresh(token);
}
};
const refresh = async refreshToken => {
const response = await fetch(refreshUrl, {
method: "POST",
mode: "cors",
headers: {
"Content-Type": "application/json",
Authorization: `JWT ${refreshToken}`
}
});
// ...
};
You can use useEffect to automatically call refresh whenever refreshToken changes:
...
if (response.status === 201) {
const token = await response.text();
setRefreshToken(token);
window.localStorage.setItem(localStorageKey, token);
//await refresh();
}
...
useEffect(
() => {
// your refresh code
},
[refreshToken]
)
The code inside useEffect will be called on the first render and after refreshToken is changed. So you don't need to call refresh after every call to setRefreshToken.

Categories

Resources