Node JS Application not taking Values from postman - node.js

I wrote two node js applications, they are fetching data properly but they are not taking post values 1st applications is this TinderClone this is just an api with no frontend i am posting data from postman and it is returning auto generated id but not the data i am posting,
Other application i cloned from github, it has proper frontend with working CRUD, but when i tried to post values from postman it wont take any values it will just add record in database with null values, so is there anything wrong im doing on postman? cause it is still working if i post data with the form on its frontend the application url is MernCRUD
Postman Screenshots:
posting data,
fetching data
Code:
//Cards Schema (Cards.js)
import mongoose from 'mongoose'
const cardSchema = mongoose.Schema({
name: String,
imgUrl: String
})
export default mongoose.model('cards', cardSchema)
//Posting Data (Server.js)
app.post('/tinder/cards', (req, res) => {
const dbCard = req.body;
Cards.create(dbCard, (err, data) => {
if(err){
res.status(500).send(err)
}
else{
res.status(201).send(data)
}
})
})
//Fetching Data
app.get('/tinder/cards', (req, res) => {
Cards.find((err, data) => {
if(err){
res.status(500).send(error);
}
else{
res.status(200).send(data);
}
});
});

in postman you don't have to add content type manually . You should select json from the drop down and it will add content type by default. **
Now you have text in your raw dropdown change to json .
**

Related

Upload either a document or image together with other form fields node express

Am developing an API for taking input information like title, description, and image or document. I have tested the API is working when I don't add the image/document part. How can I add this field to insert an image/document to the mongo DB? I can actually add info without the image/docs upload, How do I go about it?
Upload info controller
exports.upload = (req, res) =>{
const { title, category, duration, durationSys, description } = req.body
Project.findOne({ title }).exec((err, project) => {
if (project) {
return res.status(400).json({
error: 'Choose a unique title for your Project'
});
}
});
let newProject = new Project({ title, category, duration, durationSys, description});
newProject.save((err, success) => {
if (err) {
console.log('ADDING PROJECT ERROR', err);
return res.status(400).json({
error: err
});
}
res.json({
message: 'Added successfully, check your projects'
});
});
};
If you want to store the image in the MongoDB you can refer to this thread.
Store images in a MongoDB database
Personally, I would recommend uploading the image/document to a server (preferably S3 Bucket) and just storing the link to the image/document in the Database.
Read more here regarding why it's better to not store images/document on Database rather just storing a link to the image/document.

How to use JSON data from api in frontend

I followed a tutorial for making an api with express and postgres. I can get all my data in json form no problem. But I have no idea how to use the data in the frontend of a site.
These are what I have in 2 different files that are linked.
index.js:
const db = require('../queries')
router.get('/classes/:id', db.getClassById)
router.get('/classes/:id/edit', db.getClassById, (req, res) => {
res.render('dashboard/editClass')
})
queries.js:
const getClassById = (req, res) => {
const id = parseInt(req.params.id)
pool.query('SELECT * FROM classes WHERE state = 1 AND classId = $1', [id], (err, results) => {
if(err){
throw err
}
res.status(200).json(results.rows)
})
}
module.exports = {
getClassById
}
The getClassById query is called by the express middleware and automatically sends the json data to the page, which will not allow the res.render('dashboard/editClass') to work.
So how would I call this query so that I can fill in a form with the data from the query so a user can see the existing data and make any changes they want?
Thanks to Mark and Marc who commented, I realized I needed to fetch the data from my own api when rendering the front end pages. I am now using axios to get this done in node and so far it is doing exactly what I was looking for.

Data not writing to subdocuments in MongoDB

I am using Node.js + Express for backend and MongoDB for database. My problem is that when I write data to the database, the subdocuments remain empty, i.e. I am not able to write data into the subdocuments.
Response
Fields employeeInformation up to cancellationReason are all subdocuments. When I do a console.log of req.body, I can see that my fields are populated with the correct values, but in MongoDB and in the response, there is no data. I can also write fine using Postman.
Here is my app.post code:
// POST
app.post('/create-incident', (req, res) => {
let incidentNumber = functions.createIncidentNumber();
let status = 'New';
const incidentHeader = new IncidentHeader({
incidentNumber: incidentNumber,
status: status,
employeeInformation: req.body.employeeInformation,
incidentDetail: req.body.incidentDetail,
spi: req.body.spi,
investigationDetail: req.body.investigationDetail,
recommendation: req.body.recommendation,
dataPrivacyDetail: req.body.dataPrivacyDetail,
infrastructureDetail: req.body.infrastructureDetail,
dataElement: req.body.dataElement,
processIncident: req.body.processIncident,
legislation: req.body.legislation,
dataPrivacyEducation: req.body.dataPrivacyEducation,
rca: req.body.rca,
approval: req.body.approval,
auditTrail: req.body.auditTrail,
cancellationReason: req.body.cancellationReason
});
console.log(`req.body: ${JSON.stringify(req.body)}`);
incidentHeader
.save()
.then(IncidentHeader => {
res.status(200).send(JSON.stringify(IncidentHeader));
console.log('Saved to IncidentHeader.');
})
.catch(e => {
return res.status(400).send(e);
console.log('Unable to save to IncidentHeader.');
});
});
What could I be doing wrong here?
Here is the link to my GitHub project should you wish to inspect the code further. Thank you in advance.
GitHub Repo

KeystoneJS CloudinaryImage upload via API

There seems to be lack of documentation on this topic. I'm trying to upload an image and set it to avatar: { type: Types.CloudinaryImage } in my Keystone model.
I'm posting content as multipart form data with the following structure: avatar: <raw_data>. Here is how I handle this in my API:
exports.upload_avatar = function(req, res) {
if (!req.files.avatar) {
console.info('Request body missing');
return res.status(400).json({ message: 'Request body missing', code: 20 });
}
req.current_user.avatar = req.files.avatar;
req.current_user.save();
}
where current_user is a mongoose model. What I find confusing is how to set my CloudinaryImage type field to the data I receive in the API.
So, rather than just setting the avatar to the raw data (which would work fine for e.g. a string field), you'll need to go through the update handler, which calls to the {path}_upload special path in cloudinary image.
You should then be able to do avatar.getUpdateHandler, perhaps following this example.
I would like to share what worked for me. The process is kind of strange but by adding in this code, all of the model validation works just fine and cloudinary uploads are set.
post(req, res, next) {
const newBundle = new Bundle(); //A mongoose model
newBundle.getUpdateHandler(req).process(req.body, (err) => {
if (err) {
return res.status(500).json({
error: err.message,
});
}
return res.json(newBundle);
});
}
When posting to the endpoint, all you need to do is make sure you set your file fields to be {databaseFieldName}_upload.
Ok after some digging through the source code, I figured out a way to do that:
exports.upload_avatar = function(req, res) {
req.current_user.getUpdateHandler(req).process(req.files, {fields: 'avatar'}, function(err) {
if (err) {
return res.status(500).json({ message: err.message || '', code: 10 });
}
res.send('');
});
}
I had the following gotchas:
use getUpdateHandler to update CloudinaryImage field.
use "magic" naming for multipart form data fields you POST to your API: {field_name}_upload, which in my case would be avatar_upload.
process req.files, which is a dictionary with your field names as keys and your file data as values. req.body is empty due to some post-processing with multer.
invoke update handler on your keystone model (you need to fetch it with find first) rather than on a specific field. Then specify {fields: <>} to limit its scope, otherwise you could have some issues like validation errors trying to update the whole object.

Node.js: req.params vs req.body

I've been cobbling together code from a few different tutorials to build a basic todo app with the MEAN stack, using node, express, angular, and mongodb. One tutorial covered creating an api for GET, POST, and DELETE actions, but neglected the POST. So, I took it as a challenge to write a function that will update an existing todo. While I got the function working, I encountered an error involving req.params that I didn't understand.
Relevant Code:
Node:
In app.js
app.put('/api/todos/:_id', ngRoutes.update);
which leads to:
exports.update = function(req, res){
var user_id = req.cookies ?
req.cookies.user_id : undefined;
Todo.findByIdAndUpdate(req.params._id,
{ $set: {
updated_at : Date.now(),
content : req.body.formText
}}, function (err, todo) {
if (err)
res.send(err)
Todo.find({ user_id : user_id}, function(err, todos) {
if (err) res.send(err);
res.json(todos);
});
});
};
Angular:
$scope.update = function(id) {
$http.put('/api/todos/' + id, this.todo)
.success(function(data) {
console.log(data);
$scope.todos = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
Jade/HTML:
form(ng-submit="update(todo._id)")
input.update-form(ng-show="todo.updating" type="text", name="content", ng-model="todo.formText" placeholder="{{todo.content}}")
This function works fine. It updates the todo in question, and returns the entire list to be reloaded onto the page with the updated value.
However, if in the node code, I change
content : req.body.formText
to
content : req.params.formText
I get the following error as my HTTP response:
Object {
message: "Cast to string failed for value "undefined" at path "content"",
name: "CastError",
type: "string",
path: "content" }
Even while, elsewhere in the function,
req.params._id
works fine to retrieve the todo's '_id' property and use it to find the appropriate document in the database. Furthermore, when viewing the request in Firefox's developer tools, the todo object appears in JSON format under the "Params" tab.
Why does this happen? What is the difference between using req.params vs req.body, and why does the second work and the first not?
req.params is for the route parameters, not your form data.
The only param you have in that route is _id:
app.put('/api/todos/:_id', ...)
From the docs:
req.params
This property is an object containing properties mapped to
the named route “parameters”. For example, if you have the route
/user/:name, then the “name” property is available as req.params.name.
This object defaults to {}.
source: http://expressjs.com/en/4x/api.html#req.params
req.body
Contains key-value pairs of data submitted in the request
body. By default, it is undefined, and is populated when you use
body-parsing middleware such as body-parser and multer.
source: http://expressjs.com/en/4x/api.html#req.body
req.params is the part you send in the request url parameter or the header part of requests.
req.params example in postman
In example above req.params is the data we are sending in postman after ninjas in the
url.
route.delete('/ninjas/:id',function(req,res,next)
{
Ninja.findByIdAndRemove({_id:req.params.id}).then(function(ninja)
{
console.log(ninja.toString());
res.send(ninja);
})
.catch(next);
});
req.body is the part you send in body part of requests
req.body example in postman
req.body is the JSON data we are sending in postman so we can access it in the post request body part.
route.post('/ninjas',function(req,res,next)
{
Ninja.create(req.body).then(function(ninja)
{
console.log("POST"+req.body);
res.send(ninja);
})
.catch(next);
});

Resources