Converting circular structure to JSON ( where is the circulation happening? ) - javascript

Getting the error TypeError: Converting circular structure to JSON on an object which doesn't have circular references.
I have tested the object in the console and had it stringified without a problem.
Even when I console log the object before passing it into the POST request, I get it stringified without a problem.
So I don't understand that on my Node server it throws this error when it gets to placing it into the request.
I have tried using npm packages flatted and yarn add json-stringify-safe, neither of which has helped.
Could it perhaps be caused by the request itself?
Here is the file contents:
const { inventorysource: { API_channel_ID, API_channel_ID_sandbox } } = require("../../config")
const post_order = async (instance, is_production, amount, user_data, res) => {
const assemble_data = {
order: {
order_number: user_data.new_id,
reference_number: user_data.new_id,
ordered_at: String(new Date()),
total_sale_price: amount,
taxes: (amount / (100 + user_data.taxes)) * 100,
notes: `${user_data.first_name} ${user_data.last_name}`,
shipping: {
method: user_data.shipping_info.name,
address: {
name: `${user_data.first_name} ${user_data.last_name}`,
company: user_data.company,
phone: user_data.phone,
email: user_data.email,
address: user_data.address_first,
address2: user_data.address_second,
city: user_data.city,
state: user_data.state,
zip: user_data.zip,
country: user_data.country
}
},
billing: {
address: {
name: `${user_data.billing_data.first_name} ${user_data.billing_data.last_name}`,
company: user_data.billing_data.company,
phone: user_data.billing_data.phone,
email: user_data.billing_data.email,
address: user_data.billing_data.address_first,
address2: user_data.billing_data.address_second,
city: user_data.billing_data.city,
state: user_data.billing_data.state,
zip: user_data.billing_data.zip,
country: user_data.billing_data.country
}
},
dealer: null,
items: user_data.products_data
}
}
const axios_instance = await instance
const stringigied_data = JSON.stringify(assemble_data)
try {
const { data } = await axios_instance.post(
`/channels/${ is_production ? API_channel_ID : API_channel_ID_sandbox }/orders`,
stringigied_data
)
res.send({
data: user_data,
order_data: data,
order_id: user_data.new_id
})
} catch(err) {
res.send(err)
console.log(err)
}
}
module.exports = post_order
I have also tried commenting out the items: user_data.products_data to check if it might be causing it, but still the error persist.
I would expect the POST request to go through without a problem.

I think it trying to convert a JSON object that is already a JSON.
I will try to check from here up:
JSON.stringify(assemble_data)

Related

Adding new array in object

I'm working on an application that involves a somewhat complex user registration. Something similar to this.
const [data, setData] = useState({
identity: '',
people: [{
name: '',
address: [{
street: '',
city: ''
}]
}]
})
function addAddress(){
setData({
...data,
people: [
...data.people,
{
address: [
...data.people[0].address,
{
street: '',
city: ''
}
]
}
]
})
}
When a user adds a new address to a person he is registering, he should add a new address to the person and keep the previous data. But it creates a new data array with just the address data, outside of the specified person.
Could someone help me how to do this insertion into the array?
It's not the best solution i guess, but it should work
I'm using here JSON.stringify() and JSON.parse() to deep copy your previous data
function addAddress (newAddress) => {
setData((previousData) => {
let newData = JSON.stringify(previousData);
newData=JSON.parse(newData);
newData.people[0].address.push(newAddress);
return (newData);
});
}

update some field on mongodb not all. How?

I'm still learning about Node.js & MongoDB so my question is:
on Update functionality would like to update some of the fields not necessary all on them So How i can do that ?
Note: i used the same validateTask function for insert new data to tasks document.
router.put('/:id', (req, res) => {
const { error } = validateTask(req.body);
if(error) return res.status(400).send(error.details[0].message);
Task.findByIdAndUpdate(req.params.id, {
name: req.body.name,
employee: req.body.employee,
description: req.body.description,
section: req.body.section,
status: req.body.status,
updated_at: new Date()
}, { new: true })
.then ( data => {
res.status(201).send(data);
}).catch(err => {
res.status(422).send('The task with given ID was not found');
});
});
function validateTask(task) {
const schema = {
name: Joi.string().min(3).required(),
employee: Joi.string().min(3).required(),
description: Joi.string().min(3).required(),
section: Joi.string().min(3).required(),
status: Joi.boolean()
};
return Joi.validate(task, schema);
}
Remove the validateTask validation
The error is because in validateTask function you have made all the fields as required and these paramters are validated before findByIdAndUpdate.
I believe You need not have any required(mandatory field) validation to be done in update. This validation can be only done for documents that are newly inserted
For that, you can use Task.findByIdAndUpdate it will only update the fields you give to for example
User: {
name: Ahmed Gamal
email: ahmed#ahmedgamal.ga
country: Egypt
}
When used with findByIdAndUpdate and given {name: Ahmed} the result will be
User: {
name: Ahmed
email: ahmed#ahmedgamal.ga
country: Egypt
}

res.json() sends data in the form of res.data but accessing _id within it is undefined

I'm having trouble understanding why a res.json call in my app sends data (an order object) but when I try accessing a piece of that data (res.data._id) and storing it into a variable I get it as undefined. I know this piece of data exists since the console.log shows the order object's _id value but console.logging that particular piece returns undefined. What causes this behavior?
Backend logic:
router.post("/new", function(req, res) {
const productInfo = req.body.productInfo;
let order = new Order();
order.product = {
_id: productInfo.id,
name: productInfo.name,
description: productInfo.description,
price: productInfo.price,
quantity: productInfo.quantity
}
order.status = "Created";
order.total = productInfo.price * productInfo.quantity;
order.owner = {
id: req.body.id,
username: req.body.username
}
order.save().then(order => {
res.status(200).json(`Order created successfully! Created order details: ${order}`);
}).catch(err => {
console.log("Order create error: ", err.message);
});
});
Frontend logic:
let orderID = "";
return (
<PayPalButton
createOrder={(data, actions) => {
axios.post("http://localhost:4000/orders/new",
{productInfo, userID, username}
).then((res) => {
if(res.status === 200) {
console.log(res.data);
console.log(res.data._id)
orderID = res.data._id;
}
}).catch((err) => {
console.log(err);
});
return actions.order.create({
purchase_units: [{
amount: {
currency_code: "USD",
value: props.amount
}
}]
})
}}
/>
)
console.log response:
Order created successfully! Created order details: { product:
{ _id: '5e68330c8dcfa56868f1d23a',
name: 'Birdhouse',
description: 'A beautiful birdhouse',
price: 5,
quantity: 2 },
owner: { username: 'tgoandrex' },
createdAt: 2020-04-12T23:04:46.286Z,
_id: 5e93a16eb1cbc837d80167ef,
status: 'Created',
total: 10,
__v: 0 }
undefined
axios is expecting the endpoint to return a JSON object, but you're sending a string to the client:
res.status(200).json(`Order created successfully! Created order details: ${order}`);
Attempting to access res.data on the client will give you the string literal
"Order created successfully! Created order details: [elided]"
But because this is a string, the property _id does not exist on it, and so it will return undefined.
In order for this to work, you need to send just the object, rather than a string:
res.status(200).json(order);
Your /orders/new endpoint doesn't respond with JSON but with a simple string. Express's Response#json method is expecting an object that will be serialized to JSON, not a string.
You should just pass your order as single argument to the json method:
res.status(200).json(order);
otherwise, your React app won't be able to parse the JSON since it isn't a valid JSON format.

Angular6 array is not getting stored

From last couple of hours, I'm trying to set simple array but somehow its not happening.
messages : [{message: string, nickname: string, user_id: string, profile_url: string, created_at: string, type: string}];
loadMessages(channelUrl){
this.getChannel(channelUrl)
.then(channel => {
this.channel = channel;
this.getMessageList(this.channel)
.then(messageList => {
this.messageList = messageList;
console.log(this.messageList);
this.messageList.forEach((messageData)=>{
console.log(messageData.message);
this.messages.push({message: messageData.message, nickname: '', user_id: '', profile_url: '', created_at: '', type: ''});
console.log(this.messages);
});
})
.catch(error => {
return error.message;
});
})
}
last console.log is not getting printed. neither its giving any errors.
Please guide.
Champagne has helped me to find the solution. I have added try catch because of that error was not getting displayed.
this.messages
was undefined

node.js mongoose TypeError: set is not a function

Pretty new to Node.js and Mongoose.
Trying to perform a basic set action after finding the relevant object, however I get the following error:
TypeError: {found object}.set is not a function.
The following is the code causing the error:
UserProfile.find({"user": req.params.id}, function (err, userProfile) {
if (err) {
console.log("Saving User profile - Error finding user");
} else { // no error
if (userProfile) { // if userProfile is found
console.log("Saving User profile - userProfile found for user: " + userProfile);
userProfile.set ({
gender: req.body.gender,
dob: req.body.dob,
phone: req.body.phone,
phone2: req.body.phone2,
state: req.body.state,
country: req.body.country
});
}
}
});
The following is the error i receive:
TypeError: userProfile.set is not a function
If I'm trying to use the "set" function on a new object created based on the same model, it works with no issue
var userProfile = new UserProfile ();
userProfile.set ({
gender: req.body.gender,
dob: req.body.dob,
phone: req.body.phone,
phone2: req.body.phone2,
state: req.body.state,
country: req.body.country
});
The following is the model:
var mongoose = require("mongoose");
var UserProfileSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
gender: String,
phone: String,
phone2: String,
dob: Date
});
module.exports = mongoose.model ("UserProfile", UserProfileSchema);
Use findOne not find. The former returns an object as the 2nd argument in the callback, the latter returns an array as the 2nd argument in the callback.
.find returns an array of documents. try using .findOne which returns the first found document

Categories

Resources