Firestore GET Document Promise does not have a result - node.js

I am trying to retrieve a document after it is created since Firestore does not return a created document. I do get the document Reference ID each time, however, when I turn around and use it, the promise is resolved but the retuning object is non-existent it seems.
Here is my code, the part I am struggling with is the section that is nested within the first Add call to Firestore
ideasRef
.add({
ideaId: req.body.ideaId,
title: req.body.title,
description: req.body.description,
category: req.body.category,
competitorHasIt: req.body.competitorHasIt || false,
createdAt: new Date(),
createdBy: {
email: req.body.user.email,
fullName: `${req.body.user.firstName} ${req.body.user.lastName}`,
location: req.body.user.location
},
deactivated: false
})
.then(docRef => {
console.log(docRef.id)
ideasRef
.get(docRef.id)
.then(idea => {
console.log("first run")
console.log(idea.exists())
console.log(idea.data())
console.log("do those even run?")
})
What is outputted in the console is the docRef.id value and "first run". What I expected to happen it to see the 3 subsequent console.logs as well that contains information about idea
Any advice on what I am overlooking would be greatly appreciated, my end goal is to get help and realizing why my idea object seems to silently cause issues. I do not see any errors in the terminal.

This ended up being the working version.
ideasRef
.add({
ideaId: req.body.ideaId,
title: req.body.title,
description: req.body.description,
category: req.body.category,
competitorHasIt: req.body.competitorHasIt || false,
createdAt: new Date(),
createdBy: {
email: req.body.user.email,
fullName: `${req.body.user.firstName} ${req.body.user.lastName}`,
location: req.body.user.location
},
deactivated: false
})
.then(docRef => {
console.log(docRef.id)
ideasRef
.doc(docRef.id)
.get()
.then(idea => {
console.log("first run")
console.log(idea.exists())
console.log(idea.data())
console.log("do those even run?")
})

Related

Insert same records multiple times to the Mongo database with NodeJs

I want to achive funcionality, where user in the frontend writes how many posts he want to insert in the database.. He can write 1, 5, 10, 15,.. up to 50 same posts.
The posts are then the SAME in the database, just this manually generated _id is different.
At first I thought that it can be done just like that:
exports.addPost = async (req: any, res: any) => {
try {
const newPost = new Post({
title: req.body.title,
description: req.body.description,
author: req.body.author,
});
for (let i: number = 0; i < 5; i++) {
await newPost .save();
}
res.status(201).json(newContainer);
} catch (err) {
res.status(400).json(err);
}
};
Post schema:
const PostSchema = new mongoose.Schema({
title: { type: String, required: true },
description: { type: String, required: true },
author: {
type: Schema.Authors.ObjectId,
ref: "Authors",
required: true,
},
});
module.exports = mongoose.model("Posts", PostSchema);
but I am not sure, if this is really the way to go.. What is some good practice for this (assuming that the number 5 in for loop will come in req.body.. So from user input.
Thanks
You can just use the following code:
try {
await Post.create(
new Array(5).fill(true).map((_) => ({
title: req.body.title,
description: req.body.description,
author: req.body.author,
}))
);
res.status(201).json(newContainer);
} catch (err) {
res.status(400).json(err);
}
model.create does accept passing an array of (new) documents to it. By mapping a new array of size 5 (or depending on user input) to your custom document and passing it to the create function will result in multiple documents created. A huge benefit is that you only have to perform one single database call (and await it).

Axios react node post request is giving a 422 (Unprocessable Entity)

I am trying to save the desired book to my MongoDB database when I press the saved button I get a 422 error I pass in the data as an object but for some reason, the data doesn't appear in the response back from the server The data is being passed to the Axios call but for some reason, the data property always returns an empty object,
The save handler
const handleSave = (event) => {
event.preventDefault();
let save = books.filter((book) => book.id === event.target.id);
// console.log(save);
// const da/ta = ;
// console.log(data);
API.saveBook({
title: save[0].title,
authors: save[0].author,
description: save[0].description,
image: save[0].image,
})
.then((res) => {
alert("book saved");
console.log(res);
// console.log(data);
})
.catch((err) => {
// console.log(data);
console.log("book not saved");
console.log(err.response);
});
};
This is the book model and the heroku link where you can see what is being logged out
const bookSchema = new Schema({
title: { type: String, required: true },
authors: [{ type: String, required: true }],
description: { type: String, required: true },
image: { type: String },
date: { type: Date, default: Date.now },
});
Heroku Link
github
I have console.logs in my inspect so you can check those out to see the response im getting back
I have cloned this repository and tested on both your Heroku link and locally, and cannot recreate the error locally. I suspect something to do with the MongoDB server rather than a code issue. I recommend you test creating a record in the live/Heroku-attached MongoDB server using an alternative method.
Thanks,
Will Walsh
Looks like volumeInfo.description is undefined for some books. The API returns a 422 error since description is required but is not present in the request payload. You could pass a default description if the book doesn't have one.
result = {
// ...
title: result.volumeInfo.title,
description: result.volumeInfo.description || "This book doesn't have a description",
// ...
}
Or you could remove the required validation for the description field if it's not an issue.
I would recommend you rename author to authors in the result object for clarity.
result = {
// ...
authors: result.volumeInfo.authors,
// ...
}

Having trouble posting to Mongo DB after external API Call

I'm attempting to make a fetch call to News API and populate my Articles collection in Mongo DB with the data I fetch. I have two files: articles.js, and article.js. - my schema looks like the following:
// Article.js
const ArticleSchema = new Schema({
title: {
type: String,
required: true
},
author: {
type: String,
required: true
},
description: {
type: String,
required: true
},
url: {
type: String,
required: true
},
datePublished: {
type: String,
required: true
},
source: {
type: String,
required: true
}
})
In articles.js, this is what my route looks like. My logic is that I make my fetch call, wait for the JSON to return, then iterate thru that json and map all the information I need to new story objects. Once I have those objects - I want to create a new instance of an Article for each, then post them to my Articles collection in Mongo DB.
/ #route POST /articles -> adds new instance of an article to the database
router.post('/', async (req, res) => {
try {
const res = await fetch('https://newsapi.org/v2/top-headlines?country=us&category=entertainment&apiKey=63c967f7cbd84c11b263b4e4758f1693');
const data = await res.json();
data.articles.forEach(article => {
const storyData = {
title: article.title,
author: article.author,
description: article.description,
url: article.url,
datePublished: article.publishedAt,
source: article.source.name
}
// console.log(storyData)
new Article(storyData)
.save()
})
} catch (err) {
console.error(err.message)
res.status(400).json({ message: err.message })
}
})
After my forEach loop, I get the objects like so:
{
title: `'Matrix 4' Style "Shifted" From Original Trilogy, Says Neil Patrick Harris - Hollywood Reporter`,
author: 'Ryan Parker',
description: 'The actor, who appears in the fourth installment, called the upcoming film "ambitious."',
url: 'https://www.hollywoodreporter.com/heat-vision/matrix-4-style-shifted-from-original-trilogy-says-neil-patrick-harris',
datePublished: '2020-09-16T17:54:26Z',
source: 'Hollywood Reporter'
}
I'm able to get the objects I'd like with the data I need, however when I attempt to call .save(), I receive validation error similar to the following:
"ValidationError: article validation failed: author: Path author is required."
I'm thinking that it may have to do with the fact that when I make post to the DB, the request should list something along the lines of "title: req.body.title", etc... Any thoughts on what could be causing this? My goal is to simply post these to the DB as I create them. Thanks!!!

Mongoose can't save document to the database for one particular collection

I have a function
function generateInvoice(data) {
const cdate = new moment.tz('GMT').toDate();
let invoiceData = {
date: cdate,
paidStatus: true,
amount: data.amount,
userId: data.userId
}
if (data.planName && data.planTypeName) {
invoiceData.item = `${data.planName} - ${data.planTypeName}`
invoiceData.quantity = data.seats || data.slots;
}
if (data.credits) {
invoiceData.item = 'Credits';
invoiceData.quantity = data.credits;
}
return Invoice.create(invoiceData).then((data)=>{
data.invoiceId = data._id.toString().slice(-5);
return data.save().then((data)=>{console.log(data); return data.invoiceId}).catch((err)=>{
throw new ErroWithStatusCode(500, 'Sorry, we seem to be facing some issue right now. Please, try again later.', err);
})
})
}
and this is how I am using this function
return generateInvoice(invoiceData).then((data)=>{
newBooking.orderId = data;
id = data;
return newBooking.save().then((booking) => {
return booking;
}).catch((err) => {
throw new ErroWithStatusCode(500, 'Sorry, we are facing some issue right now. Please try again later.')
})
});
The issue is that I can't find invoiceData in my invoices collection. The data in the callback function of then block is the document, but I can't find the same document in the invoices collection.
All the promises are getting resolved. It is not falling in the catch block, I am receiving valid data from Invoice.create(invoiceData).
Also, newBooking.save() function is working as expected. So, that's what is bothering me the most, as to why is it not working for one specific collection.
What could be the reason behind it?
EDIT: This is the invoice schema
const InvoiceSchema = new Schema({
item: String,
paidStatus: Boolean,
quantity: String,
amount: Number,
invoiceId: String,
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
date: {type: Date, default: Date.now()},
__v: {type: Number, select: false}
}, {strict: true})
export default mongoose.model('Invoice', InvoiceSchema);
And I am not receiving any error, the booking is successful. I tried logging the data received in the then block, and it is a valid document, as I have already mentioned above.
EDIT: The following is the complete code that invovlves the use of generateInvoice function: book.js
Insted of
return Invoice.create(invoiceData).then((data)=>{...
Try
new Invoice(invoiceData).save((err,data)=>{
if(err) return console.log(err);
return data._id;
})

How can I seed objects with relational fields in Node.js

Complete Node.js beginner with strong Django background here, I am building a small platform to listen music online (MEAN stack).
I have a hard time using seeds for testing purposes, here is my attempt so far:
var TrackSchema = new Schema({
title: String,
user: { type: Schema.ObjectId, ref: 'User' }
});
Track.find({})
.remove(function () {
Track.create({
title: 'Foo',
user: User.findOne({ email: 'admin#admin.com' })._id
}, {
title: 'Bar',
user: User.findOne({ email: 'test#ŧest.com' })._id
}, function () {
console.log('Finished populating tracks');
});
});
I can't find a way to link a Track to a User. Tracks are correctly served at api/tracks but if I uncomment the line where I set a user for the track, api/tracks then return an empty list (no error message provided).
Are you using mongoose as your database wrapper? If so, it doesn't support synchronous queries.
You will have to return your User in a callback function, then have your Track.create method inside it.
User.findOne({ email: 'admin#admin.com' }, function(error, user) {
Track
.create({
title: 'Foo',
user: user._id
});
});

Resources