How to send parameters through axios get method in react? - node.js

I have a axios GET method and I need to pass parameters with the get request. I am calling the GET method in Client side (React.js) like this,
const [Cart] = useState([]);
const user = {
userId : session.userId
};
console.log(user);
useEffect((user) => {
if(session.userId !== null){
//Axios.get('http://localhost:5000/api/cart/getCart', user) <- I tried both these ways
Axios({
method: 'GET',
url: 'http://localhost:5000/api/cart/getCart',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: {},
params: {
"userId" : session.userId
}
})
.then(res => {
const cart = res.data;
let tempProducts = [];
cart.data.forEach(item => {
const singleItem = {...item};
tempProducts = [...tempProducts, singleItem];
});
this.setState(() => {
return {Cart: tempProducts};
});
})
}
console.log(Cart)
});
But in server side (node.js), it doesn't get the parameter value.
router.get('/getCart', (req, res) => {
console.log(req.body.userId) //This gives the output as undefined
User.findOne({_id: req.body.userId}
,(err, userInfo) => {
res.json(userInfo.Cart);
})
});
I implemented the uncommented axios.get request by referring to this. Can you please help me to find the error? Or can you suggest me any other method to do this? Thanks

UseEffect :
axios.get('/api', {
params: {
foo: 'bar'
}
});
Server :
function get(req, res, next) {
let param = req.query.foo
.....
}

Related

Why is react not posting res.json() to console?

I have tried so many thing but my react app is not recieving jsonData variable or res as a return from the node app. The app is working and printing to console on the node side but I can't get it to print onto the react side.
const submitForm = async (event) => {
event.preventDefault(); // Prevent default submission
const data2 = document.getElementById("miles").value;
const data =
"passenger_vehicle-vehicle_type_" +
carType +
"-fuel_source_" +
vehicleType +
"-engine_size_na-vehicle_age_na-vehicle_weight_na";
axios
.post(`http://localhost:8000/api/vehicle/`, { data, data2 })
.then((res) => {
const returnText = res.json();
console.log(returnText);
return res.json();
})
.then((jsonData) => {
console.log(jsonData);
return;
})
.catch((error) => {
console.log("got errr while posting data", error);
});
};
I edited out the api and api key.
var fetch = require('node-fetch');
exports.vehicle = (req, res) =>{
let status;
const { data, data2 } = res.body;
const values = {
"emission_factor": data,
"parameters": {
"distance": parseInt(data2),
"distance_unit": "mi",
},
};
fetch('https://AAAAAAAAAAAAAAAA', {
method: 'POST',
headers: {
'Authorization': 'Bearer MYAPIKEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(values)
})
.then((res) => {
status = res.status;
return res.json()
})
.then((jsonData) => {
console.log(jsonData);
console.log(status);
return jsonData
})
.catch((err) => {
// handle error
console.error(err);
});
res.send(req.body);
}
Working code thanks for the help:
const submitForm = async (event) => {
event.preventDefault(); // Prevent default submission
const data2 = document.getElementById("miles").value;
const data =
"passenger_vehicle-vehicle_type_" +
carType +
"-fuel_source_" +
vehicleType +
"-engine_size_na-vehicle_age_na-vehicle_weight_na";
axios
.post(`http://localhost:8000/api/vehicle/`, { data, data2 })
.then((res) => {
console.log(res.data);
return;
})
.catch((error) => {
console.log("got err while posting data", error);
});
};
Node solution in comments.
The functions inside your then() statements need to return data e.g. then((res) => {return res.json()})
You have two problems here...
Client-side, you seem to be mixing up an Axios response with a fetch() Response. You want res.data, not res.json(). Since you've tagged this with reactjs, here is where you would set the data to a state value, eg
axios.post(...).then(res => {
setSomeState(res.data)
})
Server-side, you aren't waiting for your fetch request to complete. I'd recommend using an async function
exports.vehicle = async (req, res) => {
try {
const { data, data2 } = req.body
const values = {
"emission_factor": data,
"parameters": {
"distance": parseInt(data2),
"distance_unit": "mi",
},
}
// don't mix up the Express "res" with the fetch "response"
const response = await fetch('https://AAAAAAAAAAAAAAAA', {
method: 'POST',
headers: {
'Authorization': 'Bearer MYAPIKEY',
'Content-Type': 'application/json'
},
body: JSON.stringify(values)
})
if (!response.ok) {
throw new Error(`${response.status}: ${await response.text()}`)
}
res.json(await response.json()) // respond with the data
} catch (err) {
console.error(err)
res.status(500).send(err)
}
}

Execute function from object property

i have a little problem with my code.
My expectation is, when i get the object reqHeaders to the function getQueryData
i want that the property UUID will execute the function createToken().
currently, when i running the program, it happens only at the init( first time ).
const createToken = () => {
// some logics...
return `${token}`;
};
const reqHeaders = {
UUID: **createToken()**,
"Content-Type": "application/json;charset=UTF-8"
};
const getQueryData = query => {
return axiosInstance
.post("/someAddress", { selectQuery: query }, { headers: **reqHeaders** })
.then(response => {
// some logs...
return response.data;
})
.catch(error => {
//some logs....
return error;
});
}
};
module.exports = getQueryData;
thank you,
Raz.
The solution is to move the object creation inside the body of the function.
const createToken = () => {
// some logics...
return `${token}`;
};
const getQueryData = query => {
return axiosInstance
.post("/someAddress", { selectQuery: query }, { headers: {
UUID: **createToken()**,
"Content-Type": "application/json;charset=UTF-8"
} })
.then(response => {
// some logs...
return response.data;
})
.catch(error => {
//some logs....
return error;
});
}
};
module.exports = getQueryData;
Now each time you run the function new req headers will be created and hence the UUID. What you did previously created an object once and then use the same object for each function call.

UnhandledPromiseRejectionWarning in Node App

I'm building a crypto tracker in node. I have a list of addresses in the Wallet collection. I'm wanting to perform an API call to ethplorer for each address. I'm getting the error UnhandledPromiseRejectionWarning and also req.next is not a function. I'm confused because I'm not even using a req.next anywhere.
Any idea what's causing this error?
app.get('/ethplorer', function(req, res) {
const rp = require('request-promise');
Wallet.find({}).then(function(wallets) {
var allData = [];
wallets.forEach(function(w) {
const requestOptions = {
method: 'GET',
url: `https://api.ethplorer.io/getAddressInfo/${w.address}`,
qs: {
'apiKey': 'aaa'
},
json: true
};
rp(requestOptions).then(response => {
allData.push(response);
}).catch(function(err) {
console.log(err);
});
res.render('ethereum', {user: req.user, eth: allData});
});
});
});
allData is not going to be populated, nor should you do res.render in a loop
Rewritten to use async/await, avoid then() callbacks its messy
const rp = require('request-promise')
app.get('/ethplorer', async function (req, res, next) {
try {
const requestOptions = {
method: 'GET',
qs: {
'apiKey': 'aaa'
},
json: true
}
let allData = []
for (let wallet of await Wallet.find({})) {
try {
allData.push(await rp({
...requestOptions,
url: 'https://api.ethplorer.io/getAddressInfo/' + wallet.address
}))
} catch (_) {}
}
res.render('ethereum', {
user: req.user,
eth: allData
})
} catch (e) {
next(e)
}
})

Using Sequelize Operators with values from JSON body

New to Sequelize and SQL queries in general but wondering there is a simple way to use values sent in JSON body from the client when querying the database. I tried a number of variations of the below without success.
A simple example of the server route looks like this:
builder.post('/', async (req, res) => {
let track_criteria1 = req.body.criteria1;
let track_criteria2 = req.body.criteria2;
const customPlaylist = await req.context.models.Song.findAll({
where: {
[Op.and]: [
{ criteria1: { [Op.gt]: track_criteria1 } },
{ criteria2: { [Op.gt]: track_criteria2 } }
]}
});
return res.send(customPlaylist);
});
module.exports = builder;
For context, the request from the client looks like this:
const handleSubmit = async event => {
event.preventDefault()
updateStatus(PENDING)
const response = await fetch(`http://localhost:8000/playlistbuilder/`, {
method: 'POST',
contentType: 'application/json',
body: JSON.stringify({
criteria1: state.trackCriteria.criteriaOne,
criteria2: state.trackCriteria.criteriaTwo,
})
})
const tracks = await response.json()
setcustomTracks(tracks)
setTimeout(() => {
updateStatus(SUCCESS)
}, 2000)
}
Maybe this is wishful thinking! Right now there is no error but the SQL query logs out like: WHERE ("songs"."criteria1" > NULL AND "songs"."criteria2" > NULL);
Thanks!
If anyone else ends up here. I solved it by moving the contentType into a header. The updated submit handler looks like:
const handleSubmit = async event => {
event.preventDefault()
updateStatus(PENDING)
const response = await fetch(`http://localhost:8000/playlistbuilder/`, {
headers: {
'Content-Type':'application/json'
},
method: 'POST',
body: JSON.stringify({
criteria1: state.trackCriteria.criteriaOne,
criteria2: state.trackCriteria.criteriaTwo,
}),
})
I don't know enough about this yet to explain WHY this works. I'll research that tomorrow, but it is now working.

Get body POST request in Moleculer

I use Fetch in ReactJs to send a request to api Moleculer like this :
var data ={
'ordername' : 'PUG',
'receivername' : 'AnSama'
}
fetch(url,{
method: 'POST',
header: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body : data
})
.then(res => {return res.json()})
.then(
(result) => {
alert(JSON.stringify(result));
},
(error) => {
alert('error');
}
)
Then, I want to get body of request in Moleculer (Framework of NodeJS). How can i do?
In Moleculer API Gateway the JSON body is always parsed and reachable via ctx.params. If you want to send header values to the service, use the onBeforeHook in router settings.
broker.createService({
mixins: [ApiService],
settings: {
routes: [
{
path: "/",
onBeforeCall(ctx, route, req, res) {
// Set request headers to context meta
ctx.meta.userAgent = req.headers["user-agent"];
}
}
]
}
});
In addition to the #Icebob answer, If your POST API process request Asynchronously(most likely it will)& returning a promise. Here is an example(This is how we are using) :
actions : {
postAPI(ctx) {
return new this.Promise((resolve, reject) => {
svc.postdata(ctx, (err, res) => {
if (err) {
reject(err);
} else {
resolve(res);
}
});
})
.then((res) => {
return res;
}, (err) => {
return err;
});
}
}

Resources