axios is making or redirecting to this weird url. i don't what's happening. i also check other solutions available here, but no help.
i also checked it with public api urls, but it's redirecting to same url.
i'm making request from https://d52890213a1f40e2b2XXXXXXX5ab4e.vfs.cloud9.ap-southeast-1.amazonaws.com:8081/teachers
axios method:
export function apiCall(method, url, data) {
console.log(method, url, data)
debugger
return axios[method]({
url,
params: { origin: "*" },
data
})
.then(res => {
console.log(res);
return res.data;
})
.catch((err) => {
if (err.response) {
// debugger
return Promise.reject(err.response.data);
}
else if (err.request) {
// debugger
return Promise.reject(err);
}
else {
// debugger
return Promise.reject(err);
}
});
}
console output
get https://d52890213a1f40e2b2XXXXXXX5ab4e.vfs.cloud9.ap-southeast-1.amazonaws.com:8080/api/questionset undefined
calling function
componentDidMount(){
apiCall('get', `${process.env.REACT_APP_BASE_URL}/api/questionset`)
// apiCall('get', `https://randomuser.me/api/`, undefined)
.then(data =>{
console.log(data);
if(!data.success){
throw Error(data.message);
}
else{
this.setState({
isLoading: false,
questionSets: data.questionSets
})
}
})
.catch(err=>{
debugger
console.log(err);
this.setState({
isLoading: false
})
return this.props.addError(err.message)
});
}
errors:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot GET /teachers/[object%20Object]</pre>
</body>
</html>
What about try to use Promise?
export function apiCall(method, url, data) {
return new Promise((resolve, reject) =>
axios({
method,
url,
params: { origin: "*" },
data
})
.then(res => {
resolve(res.data)
})
.catch((err) => {
if (err.response) {
// debugger
reject(err.response.data);
}
else if (err.request) {
// debugger
reject(err);
}
else {
// debugger
reject(err);
}
})
)
}
Related
everyone. I'm trying to set a cookie using epress for 24 hours. Setting also works (developer tools). For example, if I now go into standby mode and return to the application, click on something that triggers a request 'load all articles of a user', then the token is undefinded and the cookie is said to be not set. How can I fix this?
In Debugger I see the access_token cookie. So this is there, but when I check 'verifyToken.js' I get an undefined.
ladeAlleArtikelEinesUsers:
const ladeAlleArtikelEinesUsers = async (artikelId) => {
try {
await axiosInstance
.post(`/artikel/finde/${artikelId}`, { withCredentials: true })
.then(async (res) => {
//TOKEN is undefined here
if (res.data.error) {
signOut(auth)
.then(() => {
dispatch(logout());
navigate("/Login");
})
.catch((error) => {
console.log(error);
});
} else {
setArtikelEinesUsers(res.data);
setOeffneArtikelEinesUsersDialog(true);
}
});
} catch (error) {
console.log(error);
}
};
verifyToken.js
export const verifyToken = (req, res, next) => {
const token = req.cookies.access_token;
console.log("TOKEN: " + token ); //UNDEFINED
if (!token) {
return res.status(200).send({
error: true,
msg: "Authentication Failed.",
});
}
jwt.verify(token, process.env.JWT, (err, user) => {
if (err) {
return res.status(200).send({
error: true,
msg: "Authentication Failed.",
});
}
req.user = user;
next();
});
};
route
router.post("/finde/:id", verifyToken, EinArtikel);
I am Fetching data from an API in my Native App and displaying it as a List.
Below is my code:
async componentWillMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('hardwareBackPress', this.backPressed);
}
this.fetchNotifications();
}
}
async fetchNotifications() {
this.setState({refreshing: true});
const config = getAppConfig();
const cognitoToken = await this.getCognitoToken(config);
if (cognitoToken !== null) {
let headers = await this.getRequestHeaders(cognitoToken);
let body = this.getRequestBody(config);
let notificationUrl = config["notification-retrieve-api"];
return fetch(notificationUrl,
{
method: 'POST',
headers: headers,
body: body
}).then((response) => {
if (response.ok) {
return response.json();
} else {
throw new Error('Something went wrong');
}
})
.then((notifications) => {
console.log(JSON.stringify(notifications));
this.setState({
notifications,
error: null,
refreshing: false
});
}).catch((error) => {
this.setState({
notifications: [],
error,
refreshing: false
});
});
}
}
This works fine. I can retrieve the data from the API.
Now I want to separate the API code from my screen component. I will be calling "fetchNotifications" as a function in my screen component. I am trying to do so but it's not working at all.
This is what I'm doing:
async componentWillMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('hardwareBackPress', this.backPressed);
}
let response = fetchNotifications();
this.setState({
notifications: response,
error: null,
refreshing: false
})
}
}
async function fetchNotifications() { //now this function is in another component
.
.
.
.
if(cognitoToken !== null) {
let headers = await this.getRequestHeaders(cognitoToken);
let body = this.getRequestBody(config);
let notificationUrl = config["notification-retrieve-api"];
return fetch(notificationUrl,
{
method: 'POST',
headers: headers,
body: body
}).then((response) => {
if (response.ok) {
response.json();
} else {
throw new Error('Something went wrong');
}
})
.then((response) => {
return response;
}).catch((error) => {
this.setState({
notifications: [],
error,
refreshing: false
});
});
}
}
export default fetchNotifications;
Is this way correct? Anyone with a better solution?
My two cents, I always put async task in Promise, including API requests.
// API helper file
export const fetchNotifications = (params) => {
return new Promise(async (resolve, reject)=>{
try{
const headers = getHeaders(params)
const body = getBody(params)
const response = await fetch(notificationUrl,
{
method: 'POST',
headers: headers,
body: body
})
if (response.ok) {
const responseObj = await response.json();
resolve(responseObj)
} else {
throw new Error('Something went wrong');
}
} catch (e) {
// something went wrong
generalHandler(e) // logging etc.
reject(e) // for ui handling
}
}
}
then we can use it everywhere
import { fetchNotifications } from '.../APIHelper'
In your ui file :
componentWillMount() {
fetchNotifications(params)
.then((notifications) => {
console.log(JSON.stringify(notifications));
this.setState({
notifications,
error: null,
refreshing: false
});
}).catch((error) => {
this.setState({
notifications: [],
error,
refreshing: false
});
});
}
I'm pretty new to the fetch api and cant figure out why I can access response.json() locally but not once deployed.
EDIT: Just making the question clearer. When my response is NOT ok, I want to send response.json() to my errorCallBack function. This works locally and I set my error message to 'MyException'. However, when it is deployed to a new environment the parameter received by errorCallBack is a Promise with the status - 'Pending' and the catch in the errorCallBack function is hit.
Fetch:
fetch(request)
.then(response => {
if (!response.ok) {
errorCallBack(response.json());
return;
}
successCallBack();
})
.catch(error => {
console.log(error.message);
errorCallBack();
});
Error callback:
errorCallBack = (jsonResponse) => {
jsonResponse
.then(data => {
if (data) {
if (data.MyException) {
this.setErrorMessage("MyException");
return;
}
}
})
.catch(() => {
this.setErrorMessage("");
});
}
Some changes. response.json() can fail if you are returning an empty response, but you can add your logic there.
fetch(request)
.then(response => {
if (!response.ok) {
console.log(response.status) // Error code
console.log(response.statusText); // Error message
return errorCallBack(response.json()); // return response Promise
}
return successCallBack(response.json()); // This will return a Promise
})
.catch(error => {
console.log(error); // Log any error
errorCallBack(error); // return an error object
});
handle Error
errorCallBack = (response) => {
response
.then(jsonData => {
if(jsonData.myException) {
...
} else{
...
}
})
.catch(error => {
console.log(error)
...
})
}
I have this fetch call:
api<T>(url: string, headers: Request): Promise<T> {
return fetch(url, headers)
.then(response => {
if (!response.ok) {
throw new Error(response.statusText);
}
return response.json().then(data => data as T);
})
.catch((error: Error) => {
throw error;
});
}
componentDidMount(){
this.api<Array<Response>>(url, requestData)
.then(data => {
this.setState({
jobs: data
});
})
.catch(error => {
console.error(error);
});
}
But the response that I get is a stream+json so I get invalid json at .json().
I saw that there is a library that can help me: http://oboejs.com/examples
But I'm having issues using oboe and typescript (beginner) (using https://www.npmjs.com/package/#types/oboe).
I tried:
api<T>(headers: Request): Oboe<T> {
return oboe(headers)
.done(function(response) {
return response;
})
.fail(function(error: Error) {
throw error;
});
}
componentDidMount(){
this.api<Array<Response>>(requestData)
.done(data => {
this.setState({
jobs: data
});
})
.fail(error => {
console.error(error);
});
}
But there are obvious errors as I don't know what type oboe should return so I get an error Oboe is not generic.
The error means that the Oboe class/type is not generic. Like Number of String for example
From Oboe's docs it seems that oboe(param).done() takes a callback
You can transform that call into a Promise and do the rest the same way you used to do
Replacing the callback logic with a Promise
api<T>(headers: Request): Promise<T> {
return new Promise((resolve, reject) => {
oboe(headers)
.done(data => resolve(data))
.fail(err => reject(err));
});
}
Calling it (the way you did with Promise/fetch)
componentDidMount(){
this.api<Array<Response>>(url, requestData)
.then(data => {
this.setState({
jobs: data
});
})
.catch(error => {
console.error(error);
});
}
i got error every time i click button on sign-in
TypeError: Cannot read property 'then' of undefined
, but after reload error gone. can i know what happened? here's my code on login
onSignIn(e){
e.preventDefault()
this.Auth.login(this.state.signInUsername, this.state.signInPassword)
.then(res => {
this.props.history.replace('/')
})
.catch(err => {
alert(err)
})
}
and this is my auth code:
login(username, password){
axios.post('http://localhost:3000/user/login', {
username,
password
})
.then(this._checkStatus)
.then(res => {
if(res.data.success === true){
const payload = {
name: username,
}
this.setToken(payload)
return Promise.resolve(res)
}else{
console.log(res.data.message)
}
})
.catch(err => {
return Promise.reject(err)
})
}
return axios from login function.
login(username, password){
return axios.post('http://localhost:3000/user/login', {
username,
password
})
.then(this._checkStatus)
.then(res => {
if(res.data.success === true){
const payload = {
name: username,
}
this.setToken(payload)
return res;
}else{
console.log(res.data.message)
}
})
.catch(err => {
throw err;
})
}
I believe you have -two- ".then" for your axios.post.The example provided at axios site uses
axios.post('/user', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
just one .then per axios call.