I have a function that I am using axios to post data to nodeJS rest api. The problem that I am having is that axios added post a list with the object instead of just the array object. Please help me fix this.
The function receives the follow from "documents"
{
_id: '6149290b197615d32c515dab',
instantMessage: false,
isComplete: true,
},
{
_id: '614a249636503d7aa9fb138d',
instantMessage: false,
isComplete: true,
},
{
_id: '614a2bf5560184026def253a',
date: '2021-09-21',
title: 'Not getting erro',
},
{
_id: '614a2c6a560184026def253d',
date: '2021-09-21',
title: 'Every thing working',
}
my function is as follow:
async function SaveAsTemplate(documents) {
const result = await axios
.post('http:localhost/templates', {
documents,
})
.catch(function (error) {
// handle error
console.warn(error.message);
});
return result;
}
in my nodeJS project where the query is received I am console.log the data and I am getting the follow results:
documents: [
{
_id: '6149290b197615d32c515dab',
instantMessage: false,
isComplete: true,
},
{
_id: '614a249636503d7aa9fb138d',
instantMessage: false,
isComplete: true,
},
{
_id: '614a2bf5560184026def253a',
date: '2021-09-21',
title: 'Not getting erro',
},
{
_id: '614a2c6a560184026def253d',
date: '2021-09-21',
title: 'Every thing working',
}
]
How can I use axios where it only give me the object without documents in front.
When I use Postman and other tools to send query to post I do not have this problem everything come out correct. Only have issues when using axios
You're doing
const result = await axios
.post('http:localhost/templates', {
documents,
})
which is the same as:
const result = await axios
.post('http:localhost/templates', {
documents: documents,
})
try:
const result = await axios
.post('http:localhost/templates', documents)
async function SaveAsTemplate(documents) {
const result = await axios
.post('http:localhost/templates', {
headers: {
'Content-Type': 'application/json',
},
body: documents,
})
.catch(function (error) {
// handle error
console.warn(error.message);
});
return result;
}
or you can try to change array to object first and then you assign on body post
Related
I'm developing a VUE application, and I am trying to figure out how to handle post responses in Axios. I wrote it and used vue-router to make the fetch but decided to try out Axios.
Axious code:
methods: {
sendForm () {
console.log("submitHandler called - success!");
const payload = {
first_name: this.event.firstName,
last_name: this.event.lastName,
email: this.event.email,
password: this.event.password,
name: this.event.agencyName,
abbreviation: this.event.abbreviation,
type: this.event.agencyType,
address: this.event.agencyAddress,
city: this.event.agencyCity,
state: this.event.state,
zipcode: this.event.zipcode,
phone: this.event.phone,
}
axios.post(process.env.VUE_APP_API_URL+"/agency/add",payload)
.then(function (response) {
console.log('Response', response)
//reformat returned expiration date for displaying on webpage
console.log("Expiry date:", response.data.data.agency.expiry);
let expd = dayjs(response.data.data.agency.expiry).format("dddd, MMMM D YYYY");
//Write retunred values to storeage
store.user = {
id: response.data.data.user.id,
first_name: response.data.data.user.first_name,
last_name: response.data.data.user.last_name,
email: response.data.data.user.email,
agency_name: response.data.data.agency.name,
expiry_date: expd,
}
router.push("/SignUpConfirm");
})
.catch(function (error) {
console.log('Error', error.message);
Swal.fire({
icon: 'error',
title: 'Oops...',
text: error.message,
})
})
}
}
My issue/question is, for some reason, I have to use "response.data.data.foo" to drill to the response I want.
When I used the built-in view router, I just used "data.foo"
Vue-router option:
methods: {
submitHandler() {
console.log("submitHandler called - success!");
const payload = {
first_name: this.firstName,
last_name: this.lastName,
email: this.email,
password: this.password,
agency_name: this.agencyName,
abbreviation: this.abbreviation,
agency_type: this.agencyType,
agency_address: this.agencyAddress,
agency_city: this.agencyCity,
state: this.state,
zipcode: this.zipcode,
phone: this.phone,
}
const requestOptions = {
method: "POST",
body: JSON.stringify(payload),
}
fetch(process.env.VUE_APP_API_URL+"/agency/add", requestOptions)
.then((response) => response.json())
.then((response) => {
if (response.error) {
console.log("Error:", response.message);
Swal.fire({
icon: 'error',
title: 'Oops...',
text: response.message,
})
} else {
//reformat returned expiration date for displaying on webpage
console.log("Expiry date:", response.data.agency.expiry);
let expd = dayjs(response.data.agency.expiry).format("dddd, MMMM D YYYY");
//Write retunred values to storeage
store.user = {
id: response.data.user.id,
first_name: response.data.user.first_name,
last_name: response.data.user.last_name,
email: response.data.user.email,
agency_name: response.data.agency.name,
expiry_date: expd,
}
router.push("/SignUpConfirm");
}
})
}
}
Your API response is probably something like this (after parsing JSON of course)
{
data: {
user: {
......
}
}
}
For clarity, lets say it is instead returning
{
topLevel: {
nextLevel: {
......
}
}
}
so, below, toplevel would actually be data, and nextLevel would actually be user ... but, using these abstract names of toplevel and nextLevel should help illustrate why you end up with data.data in axios
axios response schema is as follows
{
data: {}, // server response
status: 200, // response status
statusText: 'OK', // response status text
headers: {}, // response headers
// etc - there's more but not relevant
}
So in
axios.post(....)
.then(function (response) {
})
then nextLevel is clearly response.data.topLevel.nextlevel
Note that the response from the server here is a property of the data property of the response variable - i.e. two "levels" inside the response variable
When using fetch
fetch(....)
.then(response => response.json())
.then(response => .....)
(it doesn't help clarity that you use response in both .then by the way, I'd use result in the second .then)
in the above, the FIRST response is
{
status: 200, // response status
statusText: 'OK', // response status text
headers: {}, // response headers
body: // a readableStream of the response body
json() {}, // method to parse the body as json
// .... etc
}
and the second response is the parsed JSON response from your server,
so in this case nextLevel is response.topLevel.nextLevel
And the response from the server here is a property of (the second) response variable
I'm having difficulties to understand how Shall I handle this type of calls. I need an initial axios.get call and loop through to make an axios.all call. This is my code:
export async function getServerSideProps(context) {
const axios = require("axios");
const options = {
method: 'GET',
url: 'xxxxx',
params: { id_user: 'xxxxx' },
headers: {
'X-RapidAPI-Host': 'xxxxxxx',
'X-RapidAPI-Key': 'xxxxxxx'
}
};
const res = axios.request(options).then(function (response) {
axios.all(response.data.users.map(user => {
axios.get('xxxxxxx', {
params: { response_type: 'short', ig: user.username, corsEnabled: 'true' },
headers: {
'X-RapidAPI-Host': 'xxxxx',
'X-RapidAPI-Key': 'xxxxxxx'
}
})
})).then(res => {
return res.data
})
})
const payload = await res;
I have an error on the page when I try to console log the payload. What's going worng with my call?
Looks like you need a return inside your map.
The below code worked for me and the unique params were updated on each request. Once you prepare your series of endpoints or whatever is unique for each request (user data per your sample code) you map over the relevant data and make all your get requests. The result returned will be an array of the responses you get back from each request once all of the requests have finished.
Regarding chaining together requests, you can use any number of .then() to kick off other actions. You mention needing an id from an initial get request, so here is a solution based on that example.
Hope you find it helpful.
const users = [{ username: '1' }, { username: '2' }, { username: '3' }];
axios
.get('https://jsonplaceholder.typicode.com/posts')
.then((res) => {
console.log(res);
// simulating getting some id you need...
const id = res.data[4].id;
console.log(id);
return id;
})
.then((id) => {
axios
.all(
users.map((user) => {
return axios.get('https://jsonplaceholder.typicode.com/posts', {
params: {
response_type: 'short',
// just an example of using id...
importantId: id,
ig: user.username,
corsEnabled: 'true',
},
headers: {
'X-RapidAPI-Host': 'xxxxxxx',
'X-RapidAPI-Key': 'xxxxxxx',
},
});
})
)
.then((res) => {
console.log(res);
});
});
I have a chat application that I'm trying to add seen functionality on it.
I'm trying to execute a query that could update all chat messages (seen) columns.
here's the schema:
const messageSchema = new mongoose.Schema({
senderId: {
type: String,
required: true
},
message: {
type: String,
required: true
},
seen: { // I'm trying to update this in all the documents !!
type: Boolean,
default: false
}
}, {timestamps: true});
const chatSchema = new mongoose.Schema({
messages: [messageSchema]
});
As you can see here, I have a seen property in the message schema (which is nested inside the chat schema)
so I just want to get a single chat, update all messages inside it and update seen column to be true
I tried that:
const messagesSeen = async (req, res) => {
const chatId = req.params.id;
await Chat.findByIdAndUpdate(
chatId,
{
$set: { 'messages.seen': true },
},
{ new: true }
)
.then((chat) => {
return res
.status(200)
.json({ chat });
})
.catch((error) => {
return res.status(500).json({ message: error.message });
});
};
but unfortunately, it didn't work
so, hope to find a solution.
thank you
You should use positional operator - $[].
await Chat.findByIdAndUpdate(
chatId,
{
$set: { "messages.$[].seen": true },
},
{
new: true
})
Working example
I am having a bit of an issue with Mongoose/MongoDB this afternoon. I have a situation where I need to return all items from a collection, and doing so means that I do not pass in any search params to mongoose.find().
This is the controller that handles the get all request:
exports.get_all_posts = async (req, res, next) => {
const { params } = req;
const { sortby } = params;
//Sortby param takes two arguments for now: most_recent, oldest
try {
const getAllPosts = await BlogPost.find({}, { _id: 0 });
console.log(getAllPosts);
if (!getAllPosts) throw new Error('Could not get blog posts.');
res.json({
posts: date_.sort(getAllPosts, sortby)
});
} catch (error) {
next(error);
}
};
This is particularly where I think the issue is coming from:
const getAllPosts = await BlogPost.find({}, { _id: 0 });
I am passing an empty search parameter and then removing the _id so that it doesn't throw an error telling me that I need to provide the _id.
However I still need to be able to pull in all of the posts. My items from this collection return as normal, just without their _id's.
Here is my model for the blog posts:
const mongoose = require('mongoose');
const BlogPostSchema = new mongoose.Schema({
date: {
type: Date,
required: true
},
title: {
type: String,
required: true
},
author: {
type: String,
required: true
},
likes: {
type: Number,
required: false
},
post_body: {
type: String,
required: true
},
description: {
type: String,
required: true
},
tags: [
{
type: String,
required: false
}
],
featuredImage: {
type: String,
required: false
},
draft: {
type: Boolean,
required: true
}
});
module.exports = mongoose.model('BlogPost', BlogPostSchema);
One thing to note is that I have not defined an _id. Mongoose automatically adds in the _id field before saving a schema, so I think it is okay without it, as it has been in the past.
Thanks in advance for reading and any input!
Just as Joe has commented, { _id: 0 } as the second parameter is making your query not return the _id field.
Also as he said, there should be no problem whatsoever with using find({}).
Since other than what has already been stated, I couldn't figure out any mistake in the code snippets you provided, I guess this error could be coming from somewhere else in your project.
exports.get_all_posts = async (req, res, next) => { const { params } = req; const { sortby } = params;
try { const getAllPosts = await BlogPost.find({}); console.log(getAllPosts); if (!getAllPosts) throw new Error('Could not get blog posts.'); res.json({ posts: date_.sort(getAllPosts, sortby) }); } catch (error) { next(error); } };
no need to {_id:0} in the find() method because this method retrieve all the documents in the db collection
I am writing an API in NodeJS in which I use Mongoose and BlueBird. Regarding promise chain, my data was supposed to go through waterfall functions but it didn't. Let my example start with getTagNames to get some JSON , feeding data to retrieveTag to query and end up with res.json().
exports.getTagValues = function (req, res) {
var userId = req.params.uid;
getTagNames(req, res)
.then(retrieveTag)
.then(function (data) {
console.log('tags', data);
res.json(200, data);
})
.catch(function(err){
console.log('err', err);
//handle Error
})
}
Here is my toy data,
function getTagNames(req, res) {
var userId = req.params.uid;
return new Promise.resolve({
'userId': userId,
'variables': [
{ id: 1, name: 'hotel', type: 'String' },
{ id: 2, name: 'location', type: 'String' }
],
})
}
The way I query data. After querying inside mongo, I check whether or not have a document with userID. In case not, insert and return document. Note Tag is my mongo model
function retrieveTag(data){
Tag.findOne({'userId': data.userId})
.exec()
.then( function(tag){
if (tag) {
console.log('result', tag);
// do something ...
return tag;
}
else {
var newTag = new Tag({
advertiserId: advertiserId,
variables: variables
});
newTag.save()
.then(function () {
console.log('newTag', newTag);
return newTag;
});
}
})
}
Here is my result (userId is 1), my expectation is console.log('tags', data); occurs after all then data should not be undefined
tags undefined
GET /api/tag/values/1 200 3ms
newTag { __v: 0,
userId: '1',
_id: 581b96090e5916cf3f5112fe,
variables:
[ { type: 'String', name: 'hotel', id: 1 },
{ type: 'String', name: 'location', id: 2 } ] }
My question is how can I fix it. If there's some unclear, please help me correct.
The explanation is a bit unclear, but if I follow you right you loose data in the promise resolvement chain.
When reading your code, I notice that retrieveTag does not return the Mongoose promise. To let .then in getTagValues use the data found in retrieveTag.
So change to this:
function retrieveTag(data){
return Tag.findOne({'userId': data.userId})
.exec()
.then( function(tag){
...
})
}