I am building an application in React. My problem is that if I navigate to the route '/factura/api/invoices/${invoiceId}' and press the edit button, it should send the information to the MongoDB database and return that everything is fine, but when I do it, I get the following error.
./node_modules/mongodb/lib/cmap/auth/gssapi.js:4:0
Module not found: Can't resolve 'dns'
Import trace for requested module:
./node_modules/mongodb/lib/index.js
./pages/facturas/api/edit/[invoiceId]/index.js
https://nextjs.org/docs/messages/module-not-found
I am not sure why I am receiving this error. This is my first part of the code located in the '/facturas/edit/[invoiceId]' folder:
const updateInvoice = async (invoiceId, status) => {
try {
const res = await fetch(`/facturas/api/edit/${invoiceId}`, {
method: 'PUT',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
senderStreet: senderStreet,
senderCity: senderCity,
senderPostalCode: senderPostalCode,
senderCountry: senderCountry,
clientName: clientName,
clientEmail: clientEmail,
clientStreet: clientStreet,
clientCity: clientCity,
clientPostalCode: clientPostalCode,
clientCountry: clientCountry,
description: description,
createdAt: createdAt,
paymentDue: createdAt,
paymentTerms: paymentTerms,
status: status,
items: items,
total: totalAmount
})
})
const data = await res.json()
router.push(`/facturas/invoices/${invoiceId}`)
toast.success(data.message)
} catch (error) {
toast.error("Something is wrong")
console.log(error)
}
}
And this is the second part of the code in the file located in the API folder:
import { MongoClient, ObjectId } from "mongodb";
async function handler(req, res) {
const { invoiceId } = req.query;
const client = await MongoClient.connect('mongodb+srv://test:test#cluster0.uusfifl.mongodb.net/invoices?retryWrites=true&w=majority', { useNewUrlParser: true });
const db = client.db();
const collection = db.collection("allInvoices");
if (req.method === "PUT") {
await collection.updateOne(
{
_id: ObjectId(invoiceId),
},
{
$set: {
senderAddress: {
street: req.body.senderStreet,
city: req.body.senderCity,
postalCode: req.body.senderPostalCode,
country: req.body.senderCountry,
},
clientName: req.body.clientName,
clientEmail: req.body.clientEmail,
clientAddress: {
street: req.body.clientStreet,
city: req.body.clientCity,
postalCode: req.body.clientPostalCode,
country: req.body.clientCountry,
},
createdAt: req.body.createdAt,
paymentDue: req.body.createdAt,
paymentTerms: req.body.paymentTerms,
description: req.body.description,
status: req.body.status,
items: req.body.items,
total: req.body.total,
},
}
);
res.status(200).json({ message: "Invoice updated successfully" });
}
client.close();
}
export default handler;
And here are all the files that I have used, in case you want to see them:
https://github.com/Fukene/tarea_database
Thanks.
I tried to reinstall MongoDB again. I checked that the routes were correct and verified that the MongoDB credentials information were correct. And everything seems to be fine. I still don't know what the problem is.
The confusing thing is that it was working well until I changed the files in folders. I suppose the problem is that the route to some file is wrong, but I haven't found where the problem is.
Edit
I found some posts that say I should move my folders to be directly in the /pages folder, and when I do that my code works perfectly. Why? It's a novice question, but I don't understand how to differentiate what is acting as frontend and what as backend.
Related
So my knowledge of NodeJS and MongoDD are non-existent (just need to do a small code update for a friend) and I'm stuck.
Need to update a single document inside a collection via a unique id but can't seem to do it.
Here's the Model (I've trimmed it down and cut out all unnecessary data). I'm trying to update the field notes inside a transaction.
In short each entry in the given (an Agent) table will have a collection of multiple Transactions & Documents. I need to update a specific Transaction with the unique _id that is auto generated.
import { Schema, model } from 'mongoose';
interface Transaction {
first_name: string;
last_name: string;
type: string;
notes: string;
}
interface Agent {
org_id: number;
transactions: Array<Transaction>;
documents: Array<string>;
}
const transactionSchema = new Schema<Transaction>({
first_name: { type: String },
last_name: { type: String },
type: { type: String },
notes: String,
});
const transactionsSchema = new Schema<Agent>({
org_id: { type: Number },
transactions: [transactionSchema],
documents: [documentTypesSchema],
});
const AgentTransaction = model<Agent>(
'agent_transaction_table',
transactionsSchema
);
export default AgentTransaction;
Here's what I tried but didn't work (obviously), again I've trimmed out all unnecessary data. Just to clarify, the endpoint itself works, but the DB update does not.
import AgentTransaction from '../models/transaction'; // the above model
transaction.put('/notes', async (req, res) => {
const { org_id, transaction_id, notes } = req.body;
try {
const notesResult = await AgentTransaction.updateOne({
'transactions._id': transaction_id,
}, {
$set: {
'notes': notes
},
});
res
.status(200)
.json({ message: 'Updated', success: true, notesResult });
} catch (error) {
res.status(400).send(error);
}
});
So I figured it out. Maybe it'll help someone else as well.
const notesResult = await AgentTransaction.updateOne({
'transactions._id': { $in: [trunc2] },
}, {
$set: {
'transactions.$.notes': notes
},
});
The main issue was that the payload object needed to target the collection folder + the wildcard + the field, not just only the field.
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,
// ...
}
I'm developing ecommerce, for this I'm using MERN, and when the user places an order, the order model takes the id on the user and through this id I can get the user's name and show it on my frontend. so far everything is working perfectly. but when I delete a user who has already placed an order and I try to view the orders. I'm getting this error:
Unhandled Rejection (TypeError): Cannot read property 'name' of null.
because the user with this id was not found.
is there any way to resolve this or not receive this error?
//Node.js
const OrderSchema = new mongoose.Schema(
{
products: [CartItemSchema],
transaction_id: {},
amount: { type: Number },
address: String,
status: {
type: String,
default: "Não está em andamento",
enum: ["Não está em andamento", "Em andamento", "Já enviado", "Concluido", "Cancelado"] // enum means string objects
},
updated: Date,
//this line makes reference to the model user
user: { type: ObjectId, ref: "User" }
},
{ timestamps: true }
);
//React
export const listOrders = (userId, token) =>{
return fetch(`${API}/order/list/${userId}`, {
method: "GET",
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`
},
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
As the other answer said, you need to nullcheck every object along the chain, alternatively, you can use optional chaining to avoid cumbersome code like so:
return (
<td>{o?.user?.name` || 'some name`}</td>
)
You have to nullcheck the user object also:
{ (o.user && o.user.name) ? o.user.name : 'abc' }
I have sent category Id to the Nodejs through this code
const catHandler = async (catId) => {
const data = Axios.put('/api/products/categories/filter', {catId: catId},
{
"headers": { "content-type": "application/json", },
}
).then( categoriesProducts => {
console.log(categoriesProducts.data.products)
})
}
and this is my route for this
router.put('/categories/filter', async (req, res) => {
try {
const findCategory = await Category.find({ _id: req.body.catId });
if (findCategory) {
const productsByCategory = await Product.find(
{ category: req.body.catId }
).then(products => {
res.status(200).json({ products });
})
}
} catch (error) {
console.log('categories filter error', error)
}
})
The products of specific category are being shown in the console.log(categoriesProducts.data.products) on the react front end side like below
0: {_id: "5f7c88756746363148792982", name: "Simple Pizza", price: 5.6, image: "1601996916374.jpg", countInStock: 434, …}
1: {_id: "5f7c88976746363148792983", name: "Smoked Pizza", price: 7.8, image: "1601996951114.jpg", countInStock: 88, …}
2: {_id: "5f7c88c56746363148792984", name: "Large Cheezy Pizza", price: 9.4, image: "1601996997474.jpg", countInStock: 434, …}
But I want to display these products on the front end side. I have tried to use axios.get method but with get method how can I can send category Id to backend. So if any one has any idea how to do that Plz guide me.
you can use the query params with get method in node js
you can get query params by req.query in nodeJs
example
passing category id from front end -
api/products/categories/filter?cid=1
getting query param in the backend
const catId = req.query.cid
You can use below code to pass parameter to API get method.
fetch("/api/products/categories/filter?catId" + catId)
.then((res) => res.json())
.then((json) => {
this.setState({
Items: json,
});
});
And also you first create new state named as Items such as below.
this.state = {
Items: []
};
And finally Iterate on Items.
BR
I am having trouble figuring out if I designed the schema correctly because I am receiving a 500 error when attempting to PATCH changes of the roles property from a profile. (Note: The 500 error just responds with an empty {}, so it isn't really informative)
Below is the profile schema:
var ProfileSchema = new Schema({
name: {
type: String,
required: true
},
roles: [{
application: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Application'
},
role: {
type: String,
required: true,
enum: [ 'admin', 'author', 'publisher' ]
}
}]
});
Each profile has a role for an application, and when I send the request to the controller action 'update', it fails:
profile update controller:
// Updates an existing Profile in the DB
export function update(req, res) {
try {
if (req.body._id) {
delete req.body._id;
}
console.log('ENDPOINT HIT...');
console.log(`REQUEST PARAM ID: ${req.params.id}`);
console.log('REQUEST BODY:');
console.log(req.body);
console.log('ENTIRE REQUEST: ');
return Profile.findByIdAsync(req.params.id)
.then(handleEntityNotFound(res))
.then(saveUpdates(req.body))
.then(respondWithResult(res))
.catch(handleError(res));
} catch(ex) {
console.error('FAILED TO UPDATE PROFILE');
return handleError(res);
}
}
I made sure that the id and body was being sent properly, and I am hitting the end point.
This is an example of the request body JSON:
{
_id: 57e58ad2781fd340563e29ff,
__updated: Thu Oct 27 2016 15:41:12 GMT-0400 (EDT),
__created: Fri Sep 23 2016 16:04:34 GMT-0400 (EDT),
name: 'test',
__v: 11,
roles:[
{ application: 57b70937c4b9fe460a235375,
role: 'admin',
_id: 58125858a36bd76d8111ba16 },
{ application: 581b299f0145b48adf8f57bd,
role: 'publisher',
_id: 581b481898eefb19ed8a73ee }
]
}
When I try to find the Profile by Id, the promise chain goes straight to the catch(handleError(res)); part of the code and shows an empty object in my console.
My handle error function:
function handleError(res, statusCode) {
console.error('HANDLE PROFILE ERROR: ', statusCode);
statusCode = statusCode || 500;
return function(err) {
console.error('PROFILE ERROR:');
console.error(JSON.stringify(err, null, 2));
res.status(statusCode).send(err);
};
}
UPDATE
I am realizing the code is breaking when it hits my saveUpdates function (Note: I am using lodash):
function saveUpdates(updates) {
/// the code is fine here ///
return function(entity) {
/// once it enters in here, is where it begins to break ///
var updated = _.merge(entity, updates);
if(updated.roles.length != updates.roles.length) {
updated.roles = updates.roles;
}
for(var i in updates.roles) {
updated.roles.set(i, updates.roles[i]);
}
return updated.saveAsync()
.then(updated => {
return updated;
});
};
}
Lesson learned: Read Documentation properly.
Since I am using bluebird promises for this application, I forgot to use .spread() within my saveUpdates() callback function.
Solution:
function saveUpdates(updates) {
return function(entity) {
var updated = _.merge(entity, updates);
if(updated.roles.length != updates.roles.length) {
updated.roles = updates.roles;
}
for(var i in updates.roles) {
updated.roles.set(i, updates.roles[i]);
}
return updated.saveAsync()
// use `.spread()` and not `.then()` //
.spread(updated => {
return updated;
});
};
}
I want to thank the following SOA that led to this conclusion: https://stackoverflow.com/a/25799076/5994486
Also, here is the link to the bluebird documentation in case anyone was curious on .spread(): http://bluebirdjs.com/docs/api/spread.html