How to get data from response if you receive an error? - reactjs

How do I get a backend error if I get a 404?
Here is my code:
export const myRequest = async (body: params) => {
try {
const result = await publicInstance.get('users', {
params: body,
});
const { data } = result;
return data;
} catch (error) {
console.error('Error:', error.message, error); // How to get data from response?
}
return {};
};

You will get the statusCode in the response, which you can track. Based on the status code you can put your customized error message.
export const myRequest = async (body: params) => {
try {
const result = await publicInstance.get('users', {
params: body,
});
const { data } = result;
return data;
} catch (error) {
if(error.statusCode == 404)
error.message = "Unable to reach server at the moment. Please try again."
console.error('Error:', error.message, error);
}
return {};
};

Related

Axios.get not returning any data

I can not get the right info on my API.
i tried this and nothing comes back
const res = () => {
axios.get('https://api.scripture.api.bible/v1/bibles', {
headers: {
'api-key': '5b5d4503884b7a2515e8cee8f4b00746',
},
})
}
Your code works fine, but you are not doing anything with the response. axios.get() returns a Promise, so you need to handle it using .then()
const res = () => {
axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
res();
or make an async function and use async await.
const res = async () => {
try {
const response = await axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
});
console.log(response);
} catch (error) {
console.log(error);
}
};
res();
Instead of console.logging you can do anything, for example use a callback function:
const res = async (callback, errorCallback) => {
try {
const response = await axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
});
callback(response);
} catch (error) {
errorCallback(error);
}
};
const onSuccess = result => {
const data = JSON.stringify(result);
alert(data)
};
const onError = error => {
alert(`Ops! An error occured: ${error}`);
};
res(onSuccess, onError);

304 Error using Netlify Functions in create-react-app

※Edited some code after posting the question. New Code below.
I am trying to use Netlify Functions to hide my API key to fetch data. However, it returns a 304 and seems to be not working.
The code below returns an error "SyntaxError: Unexpected token < in JSON at position 0" and the response code is 304.
Can anybody help me with how to improve this?
■functions/fetch-weather.js
const handler = async (event) => {
try {
const { city } = event.queryStringParameters;
const API = process.env.REACT_APP_API_KEY;
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API}`
);
const data = await response.json();
return {
statusCode: 200,
body: JSON.stringify(data),
};
} catch (error) {
console.log({ statusCode: 500, body: error.toString() });
return { statusCode: 500, body: error.toString() };
}
};
module.exports = { handler };
■getCurrentWeather.js
export const getCurrentWeather = async (
city,
setLocation,
setWeather,
setNotification
) => {
const fetchWeather = async () => {
setNotification({ status: 'pending', message: 'Loading...' });
const response = await fetch(
`/.netlify/functions/fetch-weather?city=${city}`
);
if (!response.ok) {
throw new Error('cannot get current weather data');
}
const data = await response.json();
return data;
};
try {
const data = await fetchWeather();
console.log(data);
setLocation(data.name);
const [array] = data.weather;
setWeather(array.main, array.description);
setNotification({ status: 'success', message: 'Success' });
} catch (error) {
console.log(error);
setNotification({ status: 'error', message: 'Cannot find result' });
}
};
■netlify.toml
[build]
functions = "functions"
publish = "src"
■package.json
(ran "npm i netlify-cli --save-dev")
"devDependencies": {
"netlify-cli": "^6.8.12"
}
■console images (after opening page with "netlify dev")
error
network
In your netlify function after making a request you need to use .json to get the json data
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API}`
);
const data = await response.json();

React Redux handling response after axios resubmit original request

I have a small booking program to practice ReactJS + Redux + ReduxSaga + Axios + Axios Interceptor + JWT authentication
Here is the code in the component BookingDialog after the submit button click
bookingDialog.js
const handleSubmit = (event) => {
event.preventDefault();
let payload = {
selectedDate: selectedDate,
carId : carDetail.id,
userId : user.login.id, //or pass by jwt accesstoken
remarks: remarks
}
console.log(payload);
dispatch(createBooking(payload));
}
And there is saga watcher which take latest of action createBooking to function handleCreateBooking
bookingSaga.js
export function* handleCreateBooking(action) {
try {
const response = yield call(createBooking, action.payload);
const { data } = response;
console.log("handleCreateBooking");
console.log(response);
if (data && data.result && data.result > 0){
console.log("booked successfully");
yield put(setMessageBarOpen({type: "success", content: "booked successfully"}));
yield put(setCreateBookingOpen(false));
}
else{
console.log("booked failed");
//yield put(setMessageBarOpen({type: "error", content: "booked failed"}));
//yield put(setCreateBookingOpen(false));
}
} catch (error) {
console.log(error);
}
}
bookingRequest.js
const createBooking = (payload) => {
return postUrl(apiURL.createBooking.url, payload).then((res) => {
return res
});
}
The program works as expected. Success message shown and booking dialog closed after submission.
If the jwt is expired, the program will retrieve the access token by refresh token and resubmit the original request with the new access token.
The problem is that, after the original request is sent and booking is created successfully, the follow up actions (setMessageBarOpen & setCreateBookingOpen) are not performed as the posting of original request is not under the function handleCreateBooking in bookingSaga.js
axiosInstance.js
import axios from 'axios';
import apiURL from "requests/apiURL";
const ax = axios.create();
ax.interceptors.request.use(
request => {
const accessToken = JSON.parse(localStorage.getItem('token')) && JSON.parse(localStorage.getItem('token')).accessToken;
if (accessToken) {
let auth = false;
for (const [key, value] of Object.entries(apiURL)) {
if (request.url.includes(value.url)) {
auth = value.auth;
break;
}
}
if (auth) {
request.headers.authorization = `Bearer ${accessToken}`;
}
}
return request;
},
error => {
return Promise.reject(error);
}
);
const sendRefreshToken = (refreshToken) => {
return new Promise((resolve, reject) => {
console.log("refreshToken");
postUrl(apiURL.token.url, { token: refreshToken })
.then((res) => {
console.log(res);
if (res.data) {
console.log(res.data);
localStorage.setItem('token', JSON.stringify({accessToken: res.data.accessToken, refreshToken: refreshToken}));
resolve(res);
}
})
.catch(error => {
reject(error);
});
})
}
ax.interceptors.response.use(
(response) => {
return response;
},
error => {
console.log("axios.interceptors.response");
console.log(error);
const status = error.response ? error.response.status : null;
const originalRequest = error.config;
let isRefreshing = false;
if (status === 403) {
if (!isRefreshing) {
const refreshToken = JSON.parse(localStorage.getItem('token')) && JSON.parse(localStorage.getItem('token')).refreshToken;
console.log("403, refreshToken:");
console.log(refreshToken);
isRefreshing = true;
sendRefreshToken(refreshToken)
.then(({ status }) => {
console.log(status);
if (status === 200 || status === 204) {
isRefreshing = false;
console.log("start resendRequest");
console.log(originalRequest);
return ax(originalRequest);
}
})
.catch(error => {
console.error(error);
});
}
}
return error;
}
);
export const getUrl = async (url, opt) => {
const response = await ax.get(url, opt);
return response;
}
export const postUrl = async (url, data, opt) => {
const axios_res = await ax.post(url, data, opt);
return axios_res;
}
How should I handle the response from the resubmitted original request?
Thanks.

React Saga Generator yield call undefined object

So I am using axios to call my server and get response, and tried it with redux-saga but with no success. When I console log inside my axios call I got response, but signInUser in yield call is undefined forever. What can be wrong here?
const signInUserM = async (email, password) => {
await axios
.get("https://localhost:44320/Account/token")
.then(async function(response) {
const { data } = response;
axios.defaults.headers.common = {
Authorization: `Bearer ${data.token}`
};
await axios
.post("https://localhost:44320/Login", {
email: email,
password: password
})
.then(authUser => {
console.log(authUser); // got response
return authUser;
})
.catch(error => {
console.log(error);
return error;
});
})
.catch(error => {
console.log(error);
return error;
});
};
function* signInUserG({ payload }) {
const { email, password } = payload;
try {
const signInUser = yield call(
signInUserM,
email,
password
);
console.log(signInUser); // undefined forever
if (signInUser) {
// never gets here
yield put(userSignInSuccess(signInUser.id));
}
} catch (error) {
console.log(error);
}
}
Thanks for any help!
You forgot return in signInUserM and in front of the other await as well I think.

Fetch Post Request not returning payload but return status code (200)

So I am trying to create a user using redux-form. I have an express post route on the backend. NOTE: using redux-thunk for middleware, whatwg-fetch with webpack and babel-polyfill.
routes.post('/signup', async (req, res) => {
try {
const createdUser = await userController.createUser(req.body);
const JSONCreatedUser = JSON.stringify(createdUser);
res.json({
confirmation: 'success',
result: createdUser,
});
return JSONCreatedUser;
} catch (error) {
res.statusMessage = error.toString();
res.status(409).json({
confirmation: 'failure',
error: error.toString(),
});
}
});
So the problem I am having is that when I use postman. I will get the entire user object back.
But when I submit it using form I only get
Apimanager.js
export const signUserUpApi = async (url, params) => {
try {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(params),
});
const { status, statusText } = response;
if (status === 409) {
throw new Error(statusText);
}
return response;
} catch (error) {
throw new Error(error.toString());
}
};
action.js
import constants from '../constants';
import { signUserUpApi } from '../utils/APIManager';
const signUserUpUrl = process.env.SIGN_USER_UP_URL || 'http://localhost:3000/user/signup';
export const signUserUp = (user) => {
return async (dispatch) => {
try {
const createdUser = await signUserUpApi(signUserUpUrl, user);
dispatch({
type: constants.SIGN_USER_UP,
user: createdUser,
});
return createdUser;
} catch (error) {
throw new Error(error);
}
};
};
export const signUserIn = (user) => {
return {
type: constants.SIGN_USER_UP,
user,
};
};
What I am trying to do is to get the User Object I created when I submit the form and redirect back to the page.
This is what I get back and it did create the user.
First thing, I need is why am I getting the https status code back and not the user object?
Second thing, what are the ways to redirect to the home page when a user successfully signed up logged in.

Resources