PUT inside a POST request in expressJS - express

after searching and trying a lot of different things, I find myself in front of this problem : I want to post a content and save the id to an object that belongs in another schema, I'm using mongoose.
Project.findByid is finding the good project and if I log project after modification, the item is as I want it but the save part just doesn't work.
My question is : Is it possible to do a PUT action inside of a POST request, I tried to remove the first .save and it's not working either.
app.post('/pages', (req, res) => {
var db = req.db;
var name = req.body.name;
var parent = req.body.parent;
var myId = mongoose.Types.ObjectId();
var new_content = new Content({
name: name,
_id: myId,
})
new_content.save(function (error, item) {
if (error) {console.log(error)}
})
Project.findById(parent, 'content', function (error, project) {
if (error) { console.error(error); }
project.content[name] = myId;
project.save(function (error) {
if (error) {
console.log(error)
}
res.send({
success: true
})
})
})
})

Simply use
app.all(path, callback [, callback ...])
Instead of
app.post
More info here ExpressJS Docs

Related

Svelte (Express & Axios) - http 500 error on put method

I'm at a loss. I have a svelte application (Backend: Express, Frontend: Axios). I have a MongoDB with locations. Locations have an array of bands. And I want to add bands to this array. The backend seems to work fine, at least with Postman it works. But when I try to add a band through the frontend, I get a http 500 error.
This is the back end code:
app.put('/api/locations/:location', async (req, res) => {
let location = req.params.location;
let updatedlocation = req.body;
try {
await client.connect();
const database = client.db('Concerts');
const collection = database.collection('locations');
const query = { locationname: location };
const result = await collection.updateOne(query, { $set: updatedlocation });
if (result.matchedCount === 0) {
let responseBody = {
status: "No Location under the name " + location
}
res.status(404).send(responseBody);
}
else {
res.send({ status: "Location " + location + " has been updated." });
}
} catch (error) {
res.status(500).send({ error: error.message });
}})
This is the method in the frontend:
function addConcert() {
location.concerts.push(chosenband);
console.log("http://localhost:3001/api/locations/" +name);
console.log(location);
axios.put("http://localhost:3001/api/locations/" +name, location)
.then((response) => {
alert("Konzert wurde hinzugefügt");
})
.catch((error) => {
alert("Nope");
console.log(error);
});
}
Info: the {chosenband} comes from a select. This seems to work as well, as the console logs show.
The object is correct and includes the new band:
this is the log from the browser
So the object seems fine. Also the put-url is correct.
But I always get this 500 error
Thankful for any advise!
Found the problem. I didn't instantiate the location correctly. First I instantiated it simply as
let location = {}
, that didn't work. When I instantiated it with all the attributes
let location = {example:"", second:""}
it worked. Thanks for your help

Call Nextjs API from within Netlify function

I got a serverless Netlify function like this:
exports.handler = async function(event, context) {
return {
statusCode: 200,
body: JSON.stringify({message: "Hello World"})
};
}
When called by this url <site-name>/.netlify/functions/helloworld
I do get the message {"message":"Hello World"}
I also got a pages/api/mailingList.js Nextjs API endpoint:
const axios = require('axios');
export default async function handler(req, res) {
//console.log(req.query.mail);
if (req.method === "PUT") {
axios
.put(
"https://api.sendgrid.com/v3/marketing/contacts",
{
contacts: [{ email: `${req.query.mail}` }],
list_ids: [process.env.SENDGRID_MAILING_LIST_ID],
},
{
headers: {
"content-type": "application/json",
Authorization: `Bearer ${process.env.SENDGRID_API_KEY}`,
},
}
)
.then((result) => {
res.status(200).send({
message:
"Your email has been successfully added to the mailing list. Welcome 👋",
});
})
.catch((err) => {
res.status(500).send({
message:
"Oups, there was a problem with your subscription, please try again or contact us",
});
console.error(err);
});
}
}
This mailing list API endpoint, do work when using curl from the terminal with PUT as the method:
curl -X PUT -d mail=helloworld#gmail.com https://netlify.app/api/mailingList
The API endpoint also work from the URL (/api/mailingList?mail=helloworld#gmail.com) when removing the if (req.method === "PUT") { part from the mailingList.js
However, I am NOT able to get the API endpoint to be called from within the Netlify function.
(Preferably the mailingList API should be possible to call multiple times with different mailing list IDs from the Netlify function helloworld.js based on different logic /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
To get the API endpoint to be called at all, from the function, I have tried adding a axios call from the helloworld.js to mailingList.js like this
const axios = require('axios');
exports.handler = async function(event, context) {
const mail = "helloworld#gmail.com";
// add to mailinglist
axios
.put("/api/mailingList?mail="+mail)
.then((result) => {
if (result.status === 200) {
toast.success(result.data.message);
}
})
.catch((err) => {
console.log(err);
});
}
This result in the following error from the browser: error decoding lambda response: invalid status code returned from lambda: 0
(I do not get any error msg from the Netlify log, either helloworld.js or mailingList.js)
Clearly, there is something wrong with how I call the mailigList.js from helloworld.js. Would greatly appreciate if some one could give me some advice and show me what I am doing wrong.
How can I call the API endpoint (mailigList.js) from within the Netlify function helloworld.js? (Preferably multiple times with different mailing list IDs: /api/mailingList?mail=helloworld#gmail.com&listid=xxx)
Found the solution in this article: https://travishorn.com/netlify-lambda-functions-from-scratch-1186f61c659e
const axios = require('axios');
const mail = "helloworld#gmail.com";
exports.handler = (event, context, callback) => {
axios.put("https://<domain>.netlify.app/api/mailingList?mail="+mail)
.then((res) => {
callback(null, {
statusCode: 200,
body: res.data.title,
});
})
.catch((err) => {
callback(err);
});
};

How to store third-party API array data into elephantSQL database using React.js front-end and node.js back-end?

Coding newbie here. So I've been trying to build a dictionary app using wordsapi and was trying to find a way to store the dictionary api into my back end. Below is my code on the front end using React.
const _addToQuollection = async (e) => {
e.preventDefault();
const apiUrl = 'http://127.0.0.1:3333/quollection/add';
const submitResponse = await fetch(apiUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ word: word, definition: definition }),
})
.then((response) => response)
.catch((e) => {
console.log(e);
});
console.log("word added to quollection: ", submitResponse)
if (submitResponse.status === 200) {
console.log("submit response is success")
}
}
In my console, the req body information for word and definition array pops up as so... console.log picture showing req body for string word and array definition
But the post request is only inserting into word and not definition... QUERY: INSERT INTO quollection (word) VALUES ('quote'
My backend route using Node.js looks like this...
router.post('/add', async(req, res) => {
console.log('backend reqBody: ', req.body);
const { word, definition } = req.body;
const response = await quollectionModel.addToQuollection(word, definition);
if (response.rowCount >= 1) {
console.log('def added success!')
res.sendStatus(200)
} else {
res.sendStatus(500)
}
});
And the backend model looks like this...
static async addToQuollection(word, definition) {
try {
const response = await db.result(`INSERT INTO quollection (word, definition) VALUES ($1, $2);`, [word, definition]);
return response;
} catch (error) {
console.log('error', error.message)
return error.message
}
}
This was how I created my schema...
CREATE TABLE quollection (
id serial PRIMARY KEY,
word text,
definition text[1000000]
);
And this is the result in postico...
postico screenshot with successful word column and null definition column
Ahhh I hope this was a decent enough explanation. Any help would be much appreciated T_T Thank you!

mongoose save by reference multiple document

I'd like to make new document by reference of two documents.
**app.post('/student_badge/register', async (req, res) => {
const name = req.body.name;
const category = req.body.category;
People.find({name: name}, '_id', function (err, doc) {
if (err) return handleError(err);
var obj = eval(doc);
id = obj[0]._id;
})
Badge.find({category: category}, 'points title', function (err, doc) {
if (err) return handleError(err);
var obj2 = eval(doc);
points = obj2[0].points;
title = obj2[0].title;
console.log(title + " " + points);
});
data = {
id: id,
title: title,
points: points
}
console.log("data: " + data);
const sbadge = new StudentBadge(data);
sbadge.
save()
.then(result => {
res.status(201).json({
message: 'Post created successfully!',
post: result
});
})
.catch(err => {
console.log(err);
});
});**
But I cannot call three variables like id, title, points to store them in 'data'.
How can I call variables?
Thanks
Your code does not work because the variables you are trying to access, i.e. id, title, points, are being set on a callback function that gets executed asynchronously.
I would suggest using async/await instead of callbacks so that you can thereafter use the data from the other documents you are querying in the same function. In addition, I suggest to use findOne() since you only access the first entry in db.
Something like the example below should work: (I have abstracted the middleware in a separate function for clarity to use with express)
const createStudentBadge = async (req, res, next) => {
const {name, category} = req.body;
let person, badge;
try {
person = await Person.findOne({name}); // shortcut for {name: name}
badge = await Badge.findOne({category});
} catch(err) {
// handle error
}
if (!person || !badge) {
// Handle case where no document has been found in db
// This case will not throw an error when calling find()
}
data = {
id: person._id,
title: badge.title,
points: badge.points
}
const studentBadge = new StudentBadge(data);
try {
await studentBadge.save();
} catch(err) {
// handle error
}
res.status(201).json({
message: 'Post created successfully!',
post: studentBadge
});
}
app.post('/student_badge/register', createStudentBadge);
If you wanted to perform the querying in parallel, you could make use of Promise.all() and run both queries at the same time. More info can be found at MDN documentation

all mongoose queries stall

From previous answers this probably has something to do with my connection but I can't seem to place how to find the issue. I have a few segment of codes that looks like this and the result is a stall after any model function is called
connection - prints success when the server starts
mongoose.Promise = require('bluebird');
mongoose.connect('mongodb://localhost/test', { useMongoClient: true, promiseLibrary: require('bluebird') })
.then(() => console.log('connection succesful'))
.catch((err) => console.error(err));
model.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var holdingsSchema = new Schema({
pair: String,
amount: Number
});
var holdingsModel = mongoose.model('holdingsModel', holdingsSchema);
module.exports = holdingsModel
and api endpoint
holdingsModel.find(function(err, results) {
if (err) {
console.log('there is an error')
}
return res.json(results);
}).then(results => console.log('the results: ' + results));
});
At the end of everything I receive an err: empty response.
find() needs a criteria object. The second argument is the callback. When you are using promises you don't need the callback. Finally, you have to handle the errors with catch().
holdingsModel.find({ pair: 'test' }).exec()
.then(results => res.status(200).json(results))
.catch(err => res.status(400).json(err));
The exec() is used to return a proper promise, as mentioned here.