Reading response from MongoDB after updating the database - node.js

I am trying to read/use the response from mongo db after I create a new record in the db. I am using Node JS, Angular 2/4 and Ionic 3. I am successfully able to post the request, however, I am stuck at reading the response(I get the response in JSON) Screenshot of the response in my console
Now in the js code, I am trying to get the value of FirstName. How do I access it ?
This is my ts code.
CreateProfile(){
this.Loader("Creating Account");
this.params={
FirstName:this.createDetails.get('firstName').value,
LastName:this.createDetails.get('lastName').value,
City:this.createDetails.get('city').value,
Dob:this.createDetails.get('myDate').value.formatted, //this.userDob, //this.formPersonal.get('dob').value,
State:this.createDetails.get('state').value,
EmailID:this.createAccount.get('email').value,
Phone:this.createDetails.get('phone').value,
Gender:this.createDetails.get('gender').value,
Address:this.createDetails.get('address').value,
PinCode:this.createDetails.get('pincode').value,
Password:this.createAccount.get('password').value
}
this.NewProfile.createProfile(this.params).then(res=>{
console.log(res);
})
}
I am printing my response on the console.log(res) which you can see on the attached image, I am tyring to access the values
I have tried res[0].FirstName
I have tried res.FirstName
I have got errors both times.
This is code from my router/provider file
public createProfile(options){
return new Promise((resolve, reject) => {
this.http.post(this.localUrl, options)
.map(res => res.json())
.subscribe(res => {
resolve(res);
}, (err) => {
reject(err);
});
});
}
I have removed all other codes irrelevant to this question. I am guessing this would be a very trivial issue but not able to figure out what I am missing here

I got the solution, I just had to use an array like this (below code)
this.NewProfile.createProfile(this.params).then(res=>{
console.log(res['FirstName']);
})
Didn't realize it was this straightforward

Related

JSON array from Express route is undefined in React console

I am currently working on a web app to manage an external database. I am not very familiar with express or NodeJS at this point so I wanted to ask how to send a JSON object to the client sides console without getting undefined?
I have this function to connect then select the what I need and afterwards I converted my JSON object to an array of JSON objects. It displays the data fine in the console as well.
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (err) {
console.error('Unable to connect to the database:', error);
}
info = await sequelize.query('select * from LeadsInformation', { type: QueryTypes.SELECT });
const details = JSON.stringify(info);
console.log(details);
detailsArray = JSON.parse(details);
console.log(detailsArray);
}
Everything works fine in here, I can get the data and display it in the terminal.
This is my GET route:
app.get("/list", (req, res) => {
connect();
res.json(detailsArray)
});
I have tried a couple of suggested ways based on other explanations and code snippets but none of them has worked so far so I left it like that. I thought foreaching through the data itself in the request would be a solution but it did not work. I also tried using the JSON itself and trying to display it and also tried using the body parser library. Though the library has not been updated for two years. Also I am using axios to fetch the data. It works fine when I try sending a simple string like "hello world" for example.
Is there anything that I'm missing or do you have any other solutions? I would also appreciate an explanation as well if possible.
Edit: It might also have to do something with how I am getting the response in the frontend. I'll look into that as well and will update this thread if I sort it out!
This is the way I get the response. I am currently trying to show in the console. I am using axios API.
Axios({
method: "GET",
url: "http://localhost:5000/list",
headers: {
"Content-Type": "application/json"
}
}).then(res => {
console.log(res.data.json);
});
Probably you have undefined in route because connect function doesn't return anything.
Also connect is an async function it means that it returns Promise and you have to call .then method or use await to get value from it.
Here is the code snippet with fixes that I described above.
async function connect() {
try {
await sequelize.authenticate();
console.log('Connection has been established successfully.');
} catch (err) {
console.error('Unable to connect to the database:', error);
}
info = await sequelize.query('select * from LeadsInformation', { type: QueryTypes.SELECT });
const details = JSON.stringify(info);
detailsArray = JSON.parse(details);
return detailsArray;
}
app.get("/list", async (req, res) => {
const result = await connect();
res.json(result)
});
Notice that in the router handler function I also use async and await because I call connect which is an asynchronous function.
The solution above did work and also another problem I had was that I wasn't getting the response correctly.
I ended up getting the response to the frontend after changing my code to the following from:
console.log(res.data.json);
To:
console.log(res.data[1]);

Node JS GET API's not working with new data

I am using Node JS and MYSQL. When I add new data to my project, it writes to the database. Then when I want to GET this data with another API, it doesn't come. When I try again after about a minute, it comes on. However, right after I send a request via Swagger, data comes from the outside (Postman or Panel) on my request again.
My simple Controller.
exports.GetAll = (req, res, next) => {
ThisModel.GetAllSQL()
.then((response) => {
res.status(200).json(response[0]);
}).catch((error) => {
res.status(400).send();
console.log('Senaryo listesi çekilirken bir hata meydana geldi: ' + error);
})
}
.then((response) => {
res.status(200).json(response[0]);
})
Judging from the line above, it looks like you're getting a list/array of data, but only returning the first item in the list response[0].
Maybe this is what you're looking for:
.then((response) => {
res.status(200).json(response);
})

Files not being sent in a multipart form when testing endpoint using Jest Supertest Formidable

I'm trying to test an endpoint that should receive a multipart/form-data. I'm sending a collection of images, which i want to process and save on the server or CDN. I'm using Jest, Express and Formidable.
Endpoint
router.post("/videos", async (req, res) => {
new formidable.IncomingForm().parse(req, (err, fields, files) => {
console.log('PARSE FORM');
if (err) {
console.error('Error', err);
throw err
}
console.log('Fields', fields);
console.log('Files', files);
for (const file of Object.entries(files)) {
console.log('FILE', file)
}
});
res.status(200).send('Created Video');
});
Test
describe("Video Endpoints", () => {
it('should create a new timelapse video', done => {
request
.post('/api/videos')
.field('file', 'some random value')
.attach('image', `${__dirname}/__mocks__/image.png`)
.then(res => {
console.log('THEN');
done();
})
});
});
When running the test it doesn't reach the formidable parse method.
If change my my attach method to this...
.attach('image', fs.readFileSync(`${__dirname}/__mocks__/xdebugcurlaccessingwpapi.png`))
It will reach the parse method but it sees the it as field and not a file.
If i make the same request but from my react app using fetch, it works perfectly fine.
What am i doing wrong? Been on this for a few days now lol.
Any help would be great.
Thanks.
I'm not entirely sure why but if you add
.set({connection: 'keep-alive'})
Then it works.
Final solution
request
.post('/api/videos')
.set({connection: 'keep-alive'})
.field('name', 'Richard')
.attach('image', mockImage)
.then(res => {
console.log('THEN');
done();
});
});
Would be good if someone has an understanding to why this is the case.
I think it might close the stream to image but can't be sure.

request body characters showing ? using fetch or request from quickbooks

I am using quickbooks api in a node 10.16 environment.
I am trying to get the PDF through the API.
I am getting what looks like the correct response but when I open it it shows blank
I have downloaded a file using postman directly and that file works.
I have opened both files up using notepad++ and I can see some characters on my file have ? or a square where on the postman file I see a character.
This google folder has both files
This is the main code where I grab the information from the API using fetch
return fetch(url, fetchOptions).then((response) => {
if (response.ok) {
return response.text()
}
response.text() is where the bad decoding is happening because I have saved it directly to a file or tried decoding it with TextDecoder and it always gives me bad characters.
Here is what I have tested so far
return response.arrayBuffer().then(buffer => {
let decodedValue = new util.TextDecoder('utf-8').decode(buffer)
fs.writeFile('decodetest.pdf', decodedValue, (err) => {
// throws an error, you could also catch it here
if (err) throw err;
// success case, the file was saved
console.log('decode file saved!');
});
return decodedValue;
});
rp below is using a different package response-promise. Also giving the same results.
return rp(options)
.then(function (response) {
console.log("Did a new response");
response.body
fs.writeFile('requesttest.pdf', response.body, (err) => {
// throws an error, you could also catch it here
if (err) throw err;
// success case, the file was saved
console.log('request test file saved!');
});
})
.catch(function (err) {
// Delete failed...
});

Catch superagent request error before piping

I'm trying to pipe a file from service A trough service B into my Postman cliente. Service A builds an delivers a CSV file, and service B (nodejs) has to pipe into my client.
After researching a lot I have managed to successfully pipe the files into service B and then into Postman. Now I want to handle the ugly cases: what if the request token is invalid? What if I can't find the file?
As of this moment, I have found zero documentation or examples on how successfully handle errors while piping a request using superagent.
This is what I have so far
router.post("/csv", (req, res) => {
download_csv(req.get("Authorization"), req.body.ids)
.then((response) => {
res.sendFile(path.resolve(response));
})
.catch((err) => {
res.status(error.status).json(error.response.body);
})
});
function download_csv(token, ids) {
const stream = fs.createWriteStream("filters.csv")
let request = agent
.post(`${profiles}/api/documents/csv`)
.set("authorization", token)
.send({
ids: ids,
action: DOWNLOAD_CSV_PROFILES
})
request.on("response", res => {
// Maybe I can use abort to handle this thing, but can't figure out how!
// if (res.status !== 200) request.abort()
console.log(res.status)
})
request.on("abort", () => {
console.log("aborted")
return new Promise((resolve, reject) => {
resolve("request aborted")
})
})
request.pipe(stream)
return streamToPromise(stream);
}
function streamToPromise(stream) {
return new Promise((resolve, reject) => {
stream.on("error", (err) => {
console.log("error in error")
})
stream.on("finish", () => {
console.log("File saved")
resolve(stream.path);
});
});
}
This code handles the creation of the files correctly. When I fake the token or misspell the Authorization header, I get a correct 401 response, but a file gets written anyway with its contents being the authentication error.
Can anyway give me a hint on how to:
actually catch and manage the request when fails
in such case, how to escape the piping by going back to the express context and just returning a failed express request?
Many thanks!
If I understand you correctly, simply create the fs write stream in on('response') and make a small fix on the resultion.
function download_csv(token, ids) {
return new Promise((resolve, reject) => {
let request = agent
.post(`${profiles}/api/documents/csv`)
.set("authorization", token)
.send({
ids: ids,
action: DOWNLOAD_CSV_PROFILES
})
request.on("response", res => {
// Maybe I can use abort to handle this thing, but can't figure out how!
if (res.status === 200) {
res
.on("end", resolve)
.pipe(fs.createWriteStream("filters.csv"));
} else {
reject();
}
})
request.on("abort", reject);
});
}
I'm not sure what is the "request" you're using - but assuming it's actually the request npm module that will help.
Ideally, upload the file to a temporary directory and move it when the promise is resolved, delete on rejected. This way you'll solve the issue of partial downloads.
If you want to make any on-the-fly transforms, check out my "scramjet". It'll make everything easier with promises.

Resources