How to make a put request in Nodejs - node.js

I'm writing a put method in node js and i have an error when i want to save the post it shows me an error.
Post.findOne({'imei.modele': req.query.modele, test: { $exists: true } })
.then((posts) => {
console.log(posts);
posts=aa;
posts.save().then(posts=>{
res.json('bonjour');
})
})
});
I get the following error - TypeError: posts.save is not a function
The request.find works correctly and the req.body is also good
so i need some help and thank you

Hello it's obvious to have this behavior because you re-assign the value of posts with aa :
remove this
posts=aa;
Try like this
Post.findOne({'imei.modele': req.query.modele, test: { $exists: true } })
.then((posts) => {
console.log(posts);
posts.save().then(posts=>{
res.json('bonjour');
})
})
});
if you want to edit posts before save try something like this
Post.findOne({'imei.modele': req.query.modele, test: { $exists: true } })
.then((posts) => {
console.log(posts);
posts.modele = 'updated model'
posts.save().then(posts=>{
res.json('bonjour');
})
})
});
where this like posts.modele = 'updated modele' should update modele property
Cleaner way
Post.findOneAndUpdate({'imei.modele': req.query.modele, test: { $exists: true } }, { $set : { req.body } }).then(doc=>{
res.json('success');
})

Related

NodeJS Array not filling up

Im using mongodb as a database after getting the valuation data which are more then one , i loop inside them and get the offers according to the offres_id , I asure you that the database has data inside and to querys are working correctly in fact if i console log them in each iteration i get this result
{
offre: [
{
_id: new ObjectId("63320bf87123db5691c51392"),
user_id: '63304e44aa63c519d887dac1',
brand: 'HP',
model: 'AZGGH-89855A',
photo: '16642242480661659650294043-bs-5.png',
scan_method: 'manual',
__v: 0
}
],
valuation: {
_id: new ObjectId("63320d39a5677df3cebcbdae"),
user_id: '63304e44aa63c519d887dac1',
offre_id: '63320bf87123db5691c51392',
given_price: '1236',
comment: 'no comment',
__v: 0
}
}
{
offre: [
{
_id: new ObjectId("6334202a8c7e6d90b35ee999"),
user_id: '63304e44aa63c519d887dac1',
brand: 'DELL',
model: 'AZGGH-89855A',
photo: '1664360490280Capture.PNG',
scan_method: 'manual',
__v: 0
}
],
valuation: {
_id: new ObjectId("633420be8c7e6d90b35ee99e"),
user_id: '63304e44aa63c519d887dac1',
offre_id: '6334202a8c7e6d90b35ee999',
__v: 0
}
}
but when i try storing each offre & valuation at the same array cell and return it i get this as a result
[]
However this is the code
router.get('/get', async (req, res) => {
try {
Valuation.find({ user_id: req.session.userID })
.exec()
.then(valuation => {
let myData = [];
if (valuation) {
for (let i = 0; i < valuation.length; i++) {
Offre.find({_id : valuation[i].offre_id})
.exec()
.then(offre=>{
myData.push({offre : offre, valuation : valuation[i]})
})
}
res.status(200).json(myData)
} else {
res.status(404).json('no valuations found')
}
})
.catch(error => {
res.status(500).json(error.message)
})
} catch (error) {
res.status(500).json({ error: error.message })
}
})
Since you're already using async, it would be a shame to not use await to simplify your code:
router.get("/get", async (req, res) => {
try {
const valuation = await Valuation.find({ user_id: req.session.userID }).exec();
if (valuation) {
let myData = [];
for (let i = 0; i < valuation.length; i++) {
const offre = await Offre.find({ _id: valuation[i].offre_id }).exec();
myData.push({ offre: offre, valuation: valuation[i] });
}
res.status(200).json(myData);
} else {
res.status(404).json("no valuations found");
}
} catch (error) {
res.status(500).json({ error: error.message });
}
});
You can probably also speed up the Offre query by using an $in query to retrieve all offres with one query, but that's another thing.

How can I use switch button to set value to database

Please how can i achieve this!
I have a switch button i'll like to use to control boolean value (true/false) in my MongoDB database
isBanned: {
type: Boolean,
default: false,
},
my button
<b-form-checkbox
v-model="post.isBanned"
switch
#change="isBannedUser($event, post._id)"
>
{{ post.isBanned }})
</b-form-checkbox>
What I expect to happen!
If I toggle the switch checkbox from the frontend (Nuxt), I want isbanned to be set to true and change the default false value in database. If I toggle the same checkbox again next time, I want false value to be sent to the backend and change the db value from true to false and vice versa
<script>
export default {
data() {
return {
post: {
isBanned: null,
},
}
},
methods: {
async isBannedUser(e, id) {
const data = {
isBanned: this.post.isBanned,
}
try {
const response = await this.$axios.$patch(`/api/v1/posts/${id}`, data)
} catch (error) {
console.log(error)
}
},
},
}
</script>
and my API
router.patch('/posts/:id', async (req, res) => {
try {
const banned = await Post.findByIdAndUpdate(req.params.id, req.body)
res.status(201).json({ banned })
} catch (err) {
res.json({
message: err.message,
})
}
})

Rest API call from REACT APP always return isLoaded: false

import React from 'react';
import './App.css';
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
items: [],
isLoaded: false
};
}
callAPI() {
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
componetDidMount() {
this.callAPI();
}
render() {
var { error, isLoaded, items } = this.state;
if (error) {
return <div>Error: {error.message}</div>;
} else if (!isLoaded) {
return <div>Loading...</div>;
}
else {
return (
<div className="App">
<ul>
{items.map(item => (
<li key={item.id} >
Id: {item.id} | Name: {item.name}
</li>
))}
</ul>
</div>
);
}
}
}
export default App;
console: no error.
react-developer-tool: returns
state=
{
"error": null,
"items": [],
"isLoaded": false
}
I am very new to REACT and APIs. Please guide me through, what mistake i have done here. I am unable to get the API output.
I am always getting "Loading"
The API does return the json:
{"id":"4570","name":"AR_RESUME_CNC_ROUTING"}
you need to set isLoading to true in your callApi function before every thing else, after that you need to set it false when you get the result or when you catch some error.
callAPI() {
this.setState({
isLoading: true,
});
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoading: false,
items: result.items
});
},
(error) => {
this.setState({
isLoading: false,
error
});
}
)
}
a bit explanation about the code, you always want to show loading when your api call begins, thats why we set isLoading in the beginning of the function, then when we get the result (success or failure, does not matter) the loading state should change to false, because we have at least a result!
also as an extra point you can use try {...} catch {...} finally {...} to have better code style like below:
async callApi() {
try {
this.setState({ isLoading: true })
const result = await fetch("http://localhost:4000/api/process/4570")
const data = await result.json()
this.setState({
items: result.items
});
} catch (e) {
this.setState({ error: e })
} finally {
this.setState({ isLoading: false })
}
}
It looks to me it is some sort of scope issue. You are doing:
this.setState({
isLoaded: true,
items: result.items
});
but you are calling it within the function callback of the fetch promise. So, this is probably referencing the internal Promise object.
I recommend you try this:
callAPI() {
const self = this;
fetch("http://localhost:4000/api/process/4570")
.then(res => res.json())
.then(
(result) => {
self.setState({
isLoaded: true,
items: result.items
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
self.setState({
isLoaded: false,
error
});
}
)
}
Re-reference the this, to a new variable (in this case I used self) and try your code there.
Thank you for your response, however the solution which worked for me is as below:
class GetOnlinePosts extends Component {
constructor(props) {
super(props);
this.state = {
error: null,
loading: true,
posts: null,
};
}
async componentDidMount() {
console.log("inside external_json");
const url = "http://localhost:4000/api/process/4570";
const response = await fetch(url);
const data = await response.json();
this.setState({ posts: data, loading: false })
console.log(data);
}
...........

NodeJS nested promises not working properly

I got a problem with my code.It jumps to second .then section without completing first job. After that, it goes back to first promise but never executes code inside second .then
Promise.all(jobs).then((values) => {
console.log("First!")
values.forEach(function(vals) {
vals.forEach(function(doc) {
if (doc.properties.location_i.toString() == request.body.id) {
jobs_do.push(dbo.collection("zones").find({
"geometry": {
$geoIntersects: {
$geometry: {
type: "Point",
coordinates: [
docs[values.indexOf(vals)].geometry_do.coordinates[0],
docs[values.indexOf(vals)].geometry_do.coordinates[1]
]
}
}
}
}))
}
})
})
}).then(function() {
console.log("Second!")
Promise.all(jobs_do).then((values) => {
values.forEach(function(vals) {
vals.forEach(function(doc) {
console.log(doc.properties.objectid);
});
})
});
});
It fulfills jobs_do array but Promise.all(jobs_do).then((values)) executed once when jobs_do is empty.
Console log is:
First!
Second!
Although I can't exactly replicate the setup you have above, here's a simple example that should guide you how to re-write your code so that it works as it's supposed to.
const jobs = Array.from({ length: 2 })
.map((_, idx) => {
return Promise.resolve({
id: idx + 1,
title: `Job ${idx + 1}`
})
})
const jobs_do = [];
Promise.all(jobs)
.then(values => {
console.log("first!");
for (const value of values) {
if (true) {
jobs_do.push(
Promise.resolve({
...value,
description: `This is a description for job ${value.id}`
})
);
}
}
return Promise.all(jobs_do);
})
.then(results => {
console.log("second!");
results.forEach(result => {
console.log(`[${result.id}] | ${result.title} | ${result.description}`);
});
});

How to update a model? .updateAttributes is not a function

I'm building a Node Express app, with Postgres as DB and Sequelize as ORM.
I have a router.js file:
router.route('/publish')
.put((...args) => controller.publish(...args));
controller.js which looks like this:
publish(req, res, next) {
helper.publish(req)
.then((published) => {
res.send({ success: true, published });
});
}
And a helper.js
publish(req) {
return new Promise((resolve, reject) => {
Article.findAll({
where: { id: req.query.article_id },
attributes: ['id', 'state']
})
.then((updateState) => {
updateState.updateAttributes({
state: 2
});
})
.then((updateState) => {
resolve(updateState);
});
});
}
So for example when I hit PUT http://localhost:8080/api/publish?article_id=3555 I should get:
{
"success": true,
"published": [
{
"id": 3555,
"state": 2
}
]
}
The current state of the article is 1.
However, I get the following error Unhandled rejection TypeError: updateState.updateAttributes is not a function. When I remove the updateState.updateAttributes part from my helper.js I get the response with the current state.
How do I update the state of the article correctly?
You should just change findAll with findOne , as you are just trying to find specific article by id :
Article.fineOne({ //<--------- Change here
where: { id: req.query.article_id },
attributes: ['id', 'state']
})
.then((updateState) => {
updateState.updateAttributes({state: 2}); //<------- And this will work
})
But if you still want to go with findAll and to know how to use that , Please try this and read the comments , that will clear all your doubts :
Article.findAll({
where: { id: req.query.article_id },
attributes: ['id', 'state']
})
.then((updateState) => {
// updateState will be the array of articles objects
updateState.forEach((article) => {
article.updateAttributes({ state: 2 });
});
//-------------- OR -----------------
updateState.forEach((article) => {
article.update({ state: 2 });
});
})

Resources