getting error 400 with axios post request & undefined error - node.js

I'm making a project to store the data in mysql using react-native. and node.js server
but i faced two problems One is TypeError in object : undefined and the other is getting error 400 with axios post request. I trying to another way for solve second problem (chage the param to formData - but this is doesn't work error 404) Sorry if this is a stupid mistake, as i am new to working with react native and node.js.
React native code
onPress={() => {
AsyncStorage.getItem("pubKey").then(pubKey => {
AsyncStorage.getItem("name").then(name => {
const {
data: { article }
} = axios.post("http://127.0.0.1:4000/apply",null,{
params: {
articleId: id,
apubKey: pubKey,
name: name,
},
headers: {'Content-Type' : 'application/json'},
});
alert('지원 확인')
console.log(article)
})
})
}}
[Unhandled promise rejection: TypeError: undefined is not an object (evaluating '_axios$post.data.article')]
[Unhandled promise rejection: Error: Request failed with status code 400]
node.js (apply.js)
router.post("/", function (req, res) {
console.log("req.body.params: ",req.body)
console.log("req: ",req)
Article.findAll({
attributes: ["id", "db_pubKey", "db_title", "db_wtype"],
where: {
id: req.body.articleId
}
})
.then(result => {
console.log("result : " + JSON.stringify(result));
let DB2 = JSON.stringify(result);
let DB1 = JSON.parse(DB2);
let DB = DB1[0];
if (DB) {
console.log("DB", DB);
Apply.create({
db_apubKey: req.body.params.apubKey,
db_articleId: req.body.params.articleId,
db_opubKey: DB.db_pubKey,
db_title: DB.db_title,
db_wtype: DB.db_wtype,
db_name: req.body.params.name,
db_accept: null
})
.then(result => {
console.log("result : " + result);
res.status(201).json({ result: 1 });
})
.catch(err => {
console.error("err : " + err);
});
} else {
res.json({ result: 0 });
}
})
.catch(err => {
console.error("err : " + err);
next(err);
});
});

All API calls are asynchronous, so you need to handle an asynchronous action with proper strategies like async/await or then/catch method.
With the async/await method:
onPress={async () => {
try {
const pubKey = await AsyncStorage.getItem("pubKey")
const name = await AsyncStorage.getItem("name")
const result = await axios.post("http://127.0.0.1:4000/apply", null, {
params: {
articleId: id,
apubkey: pubKey,
name: name,
},
headers: {'Content-Type' : 'application/json'},
})
const article = await result?.data?.article
alert('지원 확인')
console.log(article)
} catch (error) {
// do proper action on error/failure cases
console.log(error)
}
}}
Note: don't forget to use catch method for your API calls.
Note: as a side note, you can't call an http URL in production application, it must be an https
Note: you might need to specify the article type and pass it.
About the 400 error on your backend side:
change this line router.post("/", function (req, res) { to :
router.post("/apply", function (req, res) {
// rest of the codes ...
You've forgotten to add your API name correctly.

Related

Problem with axios and activeCampaign api

i have created firebase cloud function to create contact in activeCampain. I have problem with catch errors from activeCampaign. If i sent request direct to activeCampain from insomnia everything works correctly, but if i use firebase cloud function with axios something goes wrong.
I will show the code.
I created a contact before and now it makes another query with the same data directly to activeCampaign api:
and i get expected result. But if made same request by firebase function i get properly status code but i don't see errors response from activeCampaign
FirebaseCloud function code:
const functions = require("firebase-functions");
const axios = require("axios");
const cors = require("cors")({ origin: true });
const addTagToContact = async (contactId: string, tagId: string) => {
try {
await axios({
method: "post",
url: "https://xyz.api-us1.com/api/3/contactTags",
headers: {
"Api-Token": "api-token",
},
data: {
contactTag: {
contact: contactId,
tag: tagId,
},
},
enter code here
});
} catch (e) {
console.error(e);
}
};
export const createNewContact = functions.https.onRequest((request: { body: any; }, response: { status: (arg0: number) => void; send: (arg0: { response?: unknown; status?: string; }) => void; }) => {
cors(request, response, async () => {
const newContactData = request.body;
if(!newContactData.email || !newContactData.fieldValues) {
return response.send({
response: 'No contact data provided'
})
}
try {
const responseActiveCampaign = await axios({
method: "post",
url: "https://xyz.api-us1.com/api/3/contacts",
headers: {
"Api-Token": "api-token",
"Content-Type": "application/json"
},
data: {
contact: newContactData,
},
});
console.log('response active campaign console log', responseActiveCampaign)
await addTagToContact(responseActiveCampaign.data.contact.id, "1")
return response.send({
response: responseActiveCampaign.data
})
} catch (error) {
console.error('catch error', error);
response.status(500);
response.send({
response: error,
});
}
});
});
response from this query:
How can i fix it? I would like to get error response from activeCampaign to use on my frontend
the catch should be like this:
catch (error) {
console.error('catch error', error);
response.status(500);
response.send({
response: error.response.data,
});
}

Axios is returning undefined

My API is returning proper data when I am requesting from Postman. Even API is getting properly called from React, I checked using console.log inside the controller, but I am always getting undefined response. I am not sure what the mistake is.
const submit = async (e: SyntheticEvent) => {
e.preventDefault();
const response = await axios
.get('certificates', {
params: { sponser },
})
.then((res) => {
console.log(response); //undefined
alert(res.status); //200
alert(res); //[object Object]
});
};
Could you please help me on the same.
You need to return res in the then to have access on response:
const response = await axios
.get('certificates', {
params: { sponser },
})
.then((res) => {
console.log(response); //undefined
alert(res.status); //200
alert(res); //[object Object]
// response is not defined here!
return res;
});
console.log(response);
Shorter way:
const response = await axios
.get('certificates', {
params: { sponser }
});
console.log(response);
It seems that OP is relatively new to js - I can recommend this intro to async js: https://javascript.info/async-await

send body with "GET" method in axios

Is there anyway to send body with GET method in axios? because in postman it is possible. My backend code as below:
I'm using express.js + sequelize
const c_p_get_all = async (req, res) => {
const { category } = req.body;
const sql = `select p.id, p.p_image, p.p_name, p.p_desc, p.p_prize, p.p_size, c.c_name, cl.cl_name
from products as p
inner join collections as cl on cl.id = p.p_collection_id
inner join categories as c on c.id = cl.cl_category_id
where c.c_name = ?
order by p."createdAt" desc;`;
try {
const getData = await Product.sequelize.query(sql, {
replacements: [category],
});
if (getData[0] != "") {
res.status(200).send({
s: 1,
message: "success retrive all products",
data: getData[0],
});
} else {
res.status(404).send({
s: 0,
message: "data not found",
});
}
} catch (err) {
res.status(500).send({
message: err,
});
}
};
My Frontend with react.js + axios
const test = "woman";
axios({
headers: {
"content-type": "application/json",
},
method: "GET",
url: "http://localhost:3001/api/v1/product",
data: { category: test },
})
.then((value) => console.log(value))
.catch((error) => console.log(error.response));
It always goes to status 404, but in postman its working, I've tried to search this problem, but no clue. So is there anyway to do it in axios, or should I change my backend to POST method or change req.body to req.query?
I changed to query parameters and it worked

Server not sending correct response to frontend?

I am trying to make my server a middleman so that the frontend queries the server with a searchedValue, the server queries the API with the searchedValue, and the server returns the API response to the frontend.
Currently, the server is querying the API correctly. Here is the code and responses:
Query: http://localhost:3000/optionsAPI/AAPL
Code [server.js]:
app.get("/optionsAPI/:ticker", (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
tempJSON = json;
console.log(tempJSON);
}))
.catch(err => console.error(err)); // eslint-disable-line
res.send({ message: tempJSON });
});
Here is the code in the component:
Code [Component.js]:
useEffect(() => {
const fetchData = () => {
const url = `/optionsAPI/${searchedValue}`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
setOptions(json.option_activity || []);
}))
.catch(err => console.error(err)); // eslint-disable-line
};
debounce(fetchData());
}, [searchedValue]);
The console log is perfect! It logs tempJSON as I would expect to see it, but the res.send message is simply {"message":[]}. Therefore, the response my frontend gets is an empty []. This doesn't; make sense - the console is logging the response, so why is the frontend receiving a blank []?
Thanks in advance.
In your code you are calling an api which returns a promise, so to handle the data returned by the promise you should add your code inside .then() function, meaning you have to wait for the promise to be resolved before accessing the data and sending it to the client
app.get("/optionsAPI/:ticker", (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
fetch(url, { headers: { Accept: 'application/json' } })
.then(res => res.json()
.then((json) => {
tempJSON = json;
console.log(tempJSON);
// the response should be sent from here
res.send({ message: tempJSON });
}))
.catch(err => {
console.error(err);
// you also need to send a response when catching erros
res.status(400).send({ err });
});
});
you can use async / await to make your code much cleaner
app.get("/optionsAPI/:ticker", async (req, res) => {
var tempJSON = [];
const searchString = `${req.params.ticker}`;
const url = `API URL HERE, HIDING FOR SECURITY`;
try {
const result = await fetch(url, { headers: { Accept: 'application/json' } })
const json = await result.json()
tempJSON = json;
console.log(tempJSON);
res.send({ message: tempJSON });
} catch (error) {
console.error(error);
res.status(400).send({ error });
}
});

Axios does not return the error in the frontend?

I create a server on NodeJs by using Express and MongoDB (Mongoose) to create REST API after that I connect that API to my Frontend (ReactJS). the problem is that when I send post request from Axios, but on error (Duplicate Key) they not respond to catch and give a response on .then like that {data: "You Cannot Add Duplicate Link", status: 200, statusText: "OK", headers: Object, config: Object…}
FrontEnd:
axios
.post(`${SERVER}`, post) // Here Post is an object
.then(async res => {
await this.setState({ host: res.data._id });
})
.then(() => this.setState({ loading: false }))
.catch(async error => {
await this.setState({ error: error.res });
});
}
BackEnd:
const post_link_with_id = async (req, res) => {
await models
.create({
// Objects like obj_key: req.body.obj_model
})
.then(result => res.send(result))
.catch(err =>
err.code === 11000 ? res.send("You Cannot Add Duplicate Link") : ""
);
};
Make sure you are sending error status while send the response from the server.
The standard way to send a response is by using a status code.
Like,
res.status(statusCode).send(responseMessage);
For error in server, you should use the following response,
err.code === 11000 ? res.status(404).send("You Cannot Add Duplicate Link") : "";
Your final backend code should,
const post_link_with_id = async (req, res) => {
await models
.create({
// Objects like obj_key: req.body.obj_model
})
.then(result => res.send(result))
.catch(err =>
err.code === 11000 ? res.status(400).send("You Cannot Add Duplicate Link") : ""
);
};
You may want to change the suitable status code.
For details, check the documentation.
Also fix your front end setState() method, as suggested in the comments.

Resources