Possible Unhandled Promise Rejection (id: 0): React Native - reactjs

I know what caused this error, I explicitly removed the header from axios call to check if the code can handle the error. But my question is I have a catch block in place, but I'm still getting this -> Possible Unhandled Promise Rejection
const getUser1 = () => {
userService.getUser1().then((res) => {
setId(res.data._id);
return Promise.resolve();
}).catch((error) => Promise.reject(error));
};
const getUserComments = () => {
commentsService.getUserComments(‘user1’).then((res) => {
setComments(res.data)
return Promise.resolve();
}).catch((err) => Promise.reject(err));
};
useEffect(() => {
const onInit = async () => {
await Promise.all([
getUser1(),
getUserComments(),
]).catch((ex) => console.log(ex));
};
onInit();
}, []);

Try this version:
const getUser1 = async () => {
try{
const {data} = await userService.getUser1()
setId(data._id);
}
catch(err){
throw new Error(err)
}
};
const getUserComments = async () => {
try{
const {data} = await commentsService.getUserComments(‘user1’)
setComments(data)
}
catch(err){
throw new Error(err)
}
};
const init = useCallback(async () =>{
try{
return await Promise.all([
getUser1(),
getUserComments(),
])
}
catch(err){
console.error(err)
}
}, [])
useEffect(() => {
init();
}, [init]);

Related

SignalR connect setup in react- using useEffects

I'm using "#microsoft/signalr": "^6.0.5", and trying to set up a connection.
It is able to connect with the backend, but I am not sure if my setup looks OK for when the connection fails.
Specifically, I am wondering if the last useEffect is correctly written (the placement of the onClose clause)
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(
"https://localhost:3000/workorderHub",
{ accessTokenFactory: () => token, withCredentials: false }
)
.configureLogging(LogLevel.Information)
.withAutomaticReconnect()
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
async function start() {
if (connection) {
try {
connection
.start()
.then(() => {
connection.invoke("SubscribeToProject", projectId); // calling hub method from the client
})
.catch((err) => {
console.error(err.toString());
});
connection.on(
"OperationUpdated",
(projectId, operationId, operation) => {
// function called from the backend Hub
actions.updateSyncedOperation({ operationId, operation });
}
);
} catch (err) {
console.log({ err });
setTimeout(start, 5000);
}
} else {
connection.onclose(async () => {
await start();
});
}
}
start();
}, [connection]);
For React 18 with the new strictMode behaviour i do the following.
It only creates one connection without any errors and it seems to cleanup properly during strictmode behaviour.
export const useLiveUpdates = () => {
const [connectionRef, setConnection] = useState < HubConnection > ();
function createHubConnection() {
const con = new HubConnectionBuilder()
.withUrl(`${EnvService.getUrlHub('url')}`, {
accessTokenFactory: () => AuthService.getToken(),
})
.withAutomaticReconnect()
.build();
setConnection(con);
}
useEffect(() => {
createHubConnection();
}, []);
useEffect(() => {
if (connectionRef) {
try {
connectionRef
.start()
.then(() => {
connectionRef.on('message', () => { ...
});
})
.catch((err) => {
logger.error(`Error: ${err}`);
});
} catch (error) {
logger.error(error as Error);
}
}
return () => {
connectionRef ? .stop();
};
}, [connectionRef]);
};

Can't fetch data with Axios and React, getting an Promise and Undefined

I'm trying to fetch some data with Axios and React, But I'm having a problem resolving the promise and setting it on the state, that's weird.
Here is the Base:
export const fetchUserById = (username) => client.get(`/${username}`);
Here is the Call:
export const getUserById = async (username) => {
try {
const response = await api.fetchUserById(username);
const data = await response.data;
return data;
} catch (error) {
return error;
}
};
Here is in React:
const [user, setUser] = useState();
useEffect(() => {
const data = getUserById(params.username); // this gets the username and its working
setUser(data)
}, [])
useEffect(() => {
console.log("this is user: ", user)
}, [user])
If I console log user, I get undefined, If I console log data i get a promise.
getUserById is declared async so it implicitly returns a Promise that callers should either await or use a Promise chain on.
useEffect(() => {
const data = getUserById(params.username);
setUser(data); // <-- logs only the returned Promise object!
}, [])
async/await
useEffect(() => {
const getUser = async () => {
try {
const data = await getUserById(params.username);
setUser(data);
} catch(error) {
// handle error, log, etc...
}
};
getUser();
}, []);
Promise chain
useEffect(() => {
getUserById(params.username)
.then(data => {
setUser(data);
})
.catch(error => {
// handle error, log, etc...
});
};
}, []);
Or you could as well do:
useEffect(() => {
// fetch data
(async () => {
try {
const data = await getUserById(params.username);
// set state
setUser(data)
} catch(error) {
// handle error, log, etc...
// set init state
setUser(null)
}
})();
}, []);

TypeError: Cannot read properties of undefined (reading 'setRestaurants')

I'm working on a project where I am trying to fetch a list of restaurants from a database and display them on the screen.
When I run the code below I get this error:
TypeError: Cannot read properties of undefined (reading
'setRestaurants')
at CustomerDashPage.js:39
at async fetchList (CustomerDashPage.js:39)
at async getList (CustomerDashPage.js:32)
I know the fetch from the database works as I can console.log restaurants after I get them and all the tags from the database are the same as what is initially in the useState.
const [restaurants, setRestaurants] = useState([
{
Restaurant_id: "R763567026",
Restaurant_menuID: 0,
Restaurant_name: "Boston Pizza",
Restaurant_address: "271 Blackmarsh Rd",
Restaurant_postal: "P1Z 7A5",
Restaurant_username: "firstrest",
Restaurant_orders: ["O415052628", "O321764897", "O252073901", "O724516036"],
Restaurant_menuID: "M859068353",
Restaurant_category: "Japanese",
Restaurant_availability: true,
Restaurant_openHour: "11h00",
Restaurant_closeHour: "22h00",
},
]);
useEffect(() => {
const getList = async () => {
const fetchRest = await fetchList('R763567026');
}
getList();
}, [])
const fetchList = async (id) => {
try {
const resp = await fetch("/restaurant/id/" + id)
.then((resp) => resp.json())
.then(data => this.setRestaurants(data)).then(console.log(restaurants))
.catch(err => console.log(err));
}
catch (err) {
throw err;
console.log(err);
}
return true;
}
//Controls what happens when a restaurant is selected.
const selectRestaurant = async (id) => {
console.log(id);
};
return (
<div>
<Header />
<RestaurantList
itemList={restaurants}
component={RestaurantCard}
onSelect={selectRestaurant}
>
{" "}
</RestaurantList>
</div>
);
};
export default CustomerDash;
Any help would be much appreciated
As Abu mentioned in his answer, you need to call setRestaurants, not this.setRestaurants. Also, since you are using async/await syntax, you don't need all of those .then() calls.
const fetchList = async (id) => {
const response = await fetch(`/restaurant/id/${id}`).catch((err) => throw err);
const json = await response.json();
setRestaurants(json);
console.log(restaurants);
return true;
};
It's functional component so use setRestaurants instead of this.setRestaurants
const fetchList = async (id) => {
try {
const resp = await fetch("/restaurant/id/" + id)
.then((resp) => resp.json())
.then(data =>
setRestaurants(data))
.catch(err => console.log(err));
}
catch (err) {
throw err;
console.log(err);
}
}
After updating state, you won't get state value instantly. so your console.log(restaurants) won't work.

useState not triggers rerendering in websocket callback handler

Using web socket(#aspnet/signalr) it works fine(in component callback is receiving the message)fine, I am able to receive and trigger callback in component(connection.on("UpdateProgress"... ) inside this callback its increment counter which is state variable(numberOfFailed).. it triggers rendering only once, I set debugger and see numberOfFailed is always 0.
What's wrong here? why calling setNumberOfFailed doesn't change the value of numberOfFailed.
here is the code;
const [numberOfFailed, setNumberOfFailed] = useState(0);
const [connection, setConnection] = useState(null);
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(`${config.API_BASE_URL}update-progress`, {
transport: HttpTransportType.WebSockets,
accessTokenFactory: () => {
return `${localStorage.token}`;
},
})
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
const fetchData = async () => {
if (connection) {
try {
await connection.start();
connection.onclose((error) => {
console.info('Connection Closed:', error);
});
if (connection.state === HubConnectionState.Connected) {
connection.on('UpdateProgress', (message) => {
debugger;
if (message.count) {
setTitleText(`Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`);
} else if (message.status == 1) {
let _t = numberOfFailed + 1;
setNumberOfFailed(_t);
}
console.info('message', message);
});
}
} catch (err) {
console.log(err);
}
}
};
fetchData();
}, [connection]);
It was because react not trace the updated of variables which not explicitly defined in DependencyList. The best solution for this change the way..
This is how I solve this problem;
The main idea is using useReducer hook to update variables and use them in render.
const [connection, setConnection] = useState(null);
const [counts, dispatch] = useReducer(BaskentMobilReducer, INITIAL_VALUE);
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(`${config.API_BASE_URL}update-progress`, {
transport: HttpTransportType.WebSockets,
accessTokenFactory: () => {
return `${localStorage.token}`;
},
})
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
const fetchData = async () => {
if (connection) {
try {
await connection.start();
connection.onclose((error) => {
console.info("Connection Closed:", error);
});
if (connection.state === HubConnectionState.Connected) {
connection.on("UpdateProgress", (message) => {
if (message.count) {
setTotalCount(message.count);
setTitleText(
`Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`
);
} else if (message.status == 0) {
debugger;
dispatch({
type: "UPDATE_COUNTS_SUCCESS",
});
console.log("counts", counts);
} else if (message.status == 1) {
debugger;
dispatch({
type: "UPDATE_COUNTS_FAIL",
});
console.log("counts", counts);
}
console.info("message", message);
});
}
} catch (err) {
console.log(err);
}
}
};
fetchData();
}, [connection]);

Why am i getting an undefined output when I try to access value returned from async method

I have the following method which returns an object with 3 fields inside a different file named localStorage:
const getUserProfileData = async () => {
try {
await AsyncStorage.getItem(CONSTANTS.USER_PROFILE).then((item) => {
let retrievedProfile = JSON.parse(item);
return retrievedProfile;
});
} catch (e) {
throw e;
}
};
here is my file profile.js:
useEffect(() => {
const retrieveProfileData = async () => {
let retProfile = await localStorage.getUserProfileData();
console.log("check what: ",retProfile);
};
retrieveProfileData();
}, []);
inside the use effect, when I attempt to log out the result I get an output of:
check what: undefined
I have read other forums on similar problems to this but I can't seem to notice where I'm going wrong?
I think it has to do with you mixing async and .then(). Try this way:
const getUserProfileData = async () => {
try {
const result = await AsyncStorage.getItem(CONSTANTS.USER_PROFILE)
const retrievedProfile = JSON.parse(result);
return retrievedProfile;
} catch (e) {
throw e;
}
};
const getUserProfileData = async () => {
return AsyncStorage.getItem(CONSTANTS.USER_PROFILE);
};
useEffect(() => {
const retrieveProfileData = async () => {
try {
let retProfile = JSON.parse(await localStorage.getUserProfileData());
console.log("check what: ",retProfile);
} catch (error) {
// handle error
}
};
retrieveProfileData();
}, []);

Resources