Hi there I'm starting to Develop Restful API using Restify but I'm having problems developing [PUT].
My idea is to get the params and change it using the new params. But this code does not seem to work. Please help me out :D
server.put('/user/:_id', function (req, res, next) {
var user = {};
user._id = req.params._id;
console.log('_id === '+user);
var changes = req.params;
delete changes._id;
// delete changes._id;
for(var x in changes) {
user[x] = changes[x];
console.log('user[x] ='+user[x]);
}
db.Student.update(req.params._id, user,{multi:true,upsert:true}, function(err,data){
res.writeHead(200, {'Content-Type': 'application/json; charset=utf-8'});
res.end(JSON.stringify(user));
return next();
});
});
here is the putclient
var restify = require('restify');
var server = require('./app');
var client = restify.createJsonClient({
url: 'http://localhost:3000'
});
var testUser = {
$set:
{
"name" : "procopio magalpok",
"yearLevel" : "IX"
}
};
testUser._id = "561de16f885fb2f40d23ece",
client.put('/user/'+testUser._id, testUser , function (err, req, res, status) {
if (err) {
console.log("An error ocurred >>>>>>");
console.log(err);
} else {
console.log('id : '+testUser._id);
console.log('User updated >>>>>>>');
console.log(status);
}
});
Related
I have a api service in which there is a method to fetch data from the mongo db through node server. But i want to send the value of const userplant = localStorage.getItem("userplant"); along with the get request to the GET router in my node server so i can filter the data with a WHERE condition.
API.SERVICE.TS
getStorageLocationsList(){
this.setHeader();
const userplant = localStorage.getItem("userplant"); //I Want to send this to the GET router
return this.http.get(this.localURL + 'storagelocation/view', {headers:this.appHeader});
}
ROUTER.JS
router.get('/storagelocation/view', auth, function(req, res, next) {
StorageLocation.find({plantId : "5dd262a61120910d94326cc1"}, function (err, events) {
if (err) return next(err);
res.json(events);
});
});
I want the value of userplant next to the {plantId : "here"}
P.S.: My get request is perfectly working , i just want to send the const value along with it...
You can use queryParams to do that:
API.SERVICE.TS
getStorageLocationsList(){
this.setHeader();
const userplant = localStorage.getItem("userplant"); //I Want to send this to the GET router
return this.http.get(this.localURL + 'storagelocation/view' + '?userplant=' + userplant , {headers:this.appHeader});
}
ROUTER.JS
router.get('/storagelocation/view', auth, function(req, res, next) {
let userplant = req.query.userplant;
// you can use it now
StorageLocation.find({plantId : "5dd262a61120910d94326cc1"}, function (err, events) {
if (err) return next(err);
res.json(events);
});
});
Make the following changes in Angular, you can pass headers and parameters like this:
const httpOptions = {
headers: { 'Content-Type': 'application/json' },
params: {userplant:userplant}
};
getStorageLocationsList(){
this.setHeader();
const userplant = localStorage.getItem("userplant");
return this.http.get(this.localURL + 'storagelocation/view',httpOptions);
}
Make the following change in Node Js,you have to use body parser.
router.get('/storagelocation/view', auth, function(req, res, next) {
var plantId=req.body.plantId;
StorageLocation.find({plantId : plantId}, function (err, events) {
if (err) return next(err);
res.json(events);
});
});
In query params you can send.
getStorageLocationsList(){
this.setHeader();
const userplant = localStorage.getItem("userplant"); //I Want to send this to the GET router
const params = new HttpParams().set('userplant ',userplant);
return this.http.get(this.localURL + 'storagelocation/view', {headers:this.appHeader, params: params});
}
I wrote the unit tests:
var app = require('../server');
var chai = require('chai');
var supertest = require("supertest")(app);
var GoogleUrl = require('google-url');
var config = require('../config');
var expect = chai.expect;
describe('Urls Tests', function () {
var url = {
author : 'Alexey',
description : 'grrggr',
full_url : 'https://github.com',
date : '30-06-2017',
time : '18:21:27',
count_click : 0,
list_tags : [
'Sport',
'Football'
]
};
var token;
beforeEach(function (done) {
agent
.post('http://localhost:8000/auth/login')
.send({email: 'Keane95#yandex.ru', password: '123456'})
.end(function (err, res) {
if (err) {
return done(err);
}
expect(res.body.userData).to.have.property('token');
token = res.body.userData.token;
done();
});
});
it('should create a url', function(done) {
var googleUrl = new GoogleUrl({
'key': config.get('google_key')
});
googleUrl.shorten(url.full_url, function (err, shortUrl) {
url.short_url = shortUrl;
supertest
.post('/urls/create')
.send(url)
.expect(401)
.end(function (err, res) {
if (err) return done(err);
expect(res.body.author).to.equal('Alexey');
url = res.body;
done();
});
});
});
it('should modify a url by id', function(done) {
url.description = 'Good description';
url.list_tags.push('Liverpool');
supertest
.put('/urls/' + url._id)
.send(url)
.expect(401)
.end(function(err, res) {
if (err) return done(err);
expect(res.body.description).to.equal('Good description');
expect(res.body.list_tags[2]).to.equal('Liverpool');
done();
});
});
it('should modify a count of clicks', function(done) {
url.count_click++;
supertest
.put('/urls/' + url._id)
.send(url)
.expect(401)
.end(function(err, res) {
if (err) return done(err);
expect(res.body).to.equal('Count of the click is updated');
done();
});
});
});
I run to execute the unit tests and get the errors:
I read the articles by unit tests.
First article: http://developmentnow.com/2015/02/05/make-your-node-js-api-bulletproof-how-to-test-with-mocha-chai-and-supertest/
Second article: https://www.codementor.io/olatundegaruba/integration-testing-supertest-mocha-chai-6zbh6sefz
I don't understand why I get these errors. Please, help me. I think that I made little error, but since I cannot fint it.
UPDATED
I added route:
var express = require('express');
var GoogleUrl = require('google-url');
var _ = require('lodash');
var token = require('../middlewares/token');
var Url = require('../models/url');
var config = require('../config');
var router = express();
router.post('/create', token.required, createShortUrl);
router.put('/count/:id', token.required, updateCountClick);
router.put('/:id', token.required, updateUrlById);
module.exports = router;
function createShortUrl(req, res) {
_.trim(req.body.list_tags);
var tags = _.split(req.body.list_tags, ',');
tags.splice(tags.length - 1, 1);
var date = returnDate();
var time = returnTime();
var googleUrl = new GoogleUrl({
'key': config.get('google_key')
});
googleUrl.shorten(req.body.full_url, function (err, shortUrl) {
if (err) {
res.status(500).json(err);
}
var url = new Url({
'author': req.payload.username,
'description': req.body.description,
'full_url': req.body.full_url,
'short_url': shortUrl,
'list_tags': tags,
'date': date,
'time': time
});
url.save(function (err, url) {
if (err) {
return res.status(500).json(err);
} else {
return res.status(200).json(url);
}
});
});
}
function updateCountClick(req, res) {
var count_click = req.body.count_click + 1;
Url.findOneAndUpdate({_id: req.params.id}, {$set: {count_click: count_click}}, {new: true}, function (err, url) {
if (err) {
return res.status(500).json(err);
}
if (url) {
return res.status(200).json('Count of the click is updated');
}
});
}
function updateUrlById(req, res) {
_.trim(req.body.list_tags);
var tags = _.split(req.body.list_tags, ',');
tags.splice(tags.length - 1, 1);
Url.findOneAndUpdate({_id: req.params.id}, {$set: {description: req.body.description, list_tags: tags}}, {new: true}, function (err, url) {
if (err) {
res.status(500).json(err);
}
if (url) {
res.status(200).json(url);
}
});
}
UPDATED 2
Authoziration was added:
var token;
beforeEach(function (done) {
agent
.post('http://localhost:8000/auth/login')
.send({email: 'Keane95#yandex.ru', password: '123456'})
.end(function (err, res) {
if (err) {
return done(err);
}
expect(res.body.userData).to.have.property('token');
token = res.body.userData.token;
done();
});
});
Also I updated code my unit-tests.
I can't see where in your code you send 401 and Url. So it seems that your test requests are getting rejected by token.required middleware with 401 status code (which means "unauthorized").
.send(url)
.expect(401) // why do you expect 401? You never send it inside your logic
So basically your test never hit actual code.
First of all, you do need to fake authorization to make token.required middleware happy.
Then expect 200 result
.send(url)
.expect(200) // normal execution flow of createShortUrl results in 200
.end(/* rest of your test logic */)
I am trying to download more that 100 files at the same time. But when I execute the downloading function my macbook freezes(unable to execute new tasks) in windows also no download(but doesn't freeze) and no download progress in both case(idle network).
Here is my download module:
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
for (var i = 0; i < docs.length; i++) {
//todo scraping
var video = youtubedl(docs[i].url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs[i].id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err)console.log(err);
else console.log('Download completed!')
});
});
}
}
});
});
module.exports = router;
Now can anyone please help me here? I am using this module for downloading files.
The solution is using async in this case.
Try it this way....with async.each()
var express = require('express');
var router = express.Router();
var fs = require('fs');
var youtubedl = require('youtube-dl');
var links = require('../models/Links');
var async = require('async')
router.get('/', function (req, res, next) {
links.find({dlStatus: false}, function (err, docs) {
if (err) {
console.log(err);
res.end();
} else if (!docs) {
console.log('No incomplete downloads!');
res.end();
} else {
async.each(docs,function(doc,cb){
var video = youtubedl(doc.url, [], {cwd: __dirname});
// Will be called when the download starts.
video.on('info', function (info) {
console.log('Download started');
console.log(info);
});
video.pipe(fs.createWriteStream('./downloads/' + docs.id + '-' + i + '.mp4'));
video.on('complete', function complete(info) {
links.findOneAndUpdate({url: info.webpage_url}, {dlStatus: true}, function (err, doc) {
if (err){
console.log(err);
cb(err);
}
else {
console.log('Download completed!');
cb()
}
});
});
},function(err){
if(err)
return console.log(err);
console.log("Every thing is done,Here!!");
})
}
});
});
module.exports = router;
And you can process every thing in batch too using async.eachLimits().
I got a problem with Multer, undefined req.files.path field
First, my Express.js route is:
routes.js
router.post('/', function(req, res, next){
// id, name, usersArray[], info, iconImg, headerImg
var dataObject = new MyMongooseDataObject();
// Receive data
dataObject.id = uuid.v4();
dataObject.name = req.body.name;
dataObject.usersArray = req.body.usersArray;
dataObject.info = req.body.info;
return someBindingWrapperToStoreTheFile.postFile(uuid.v4(), [req.files.iconImg.path.toString(), req.files.headerImg.path.toString()])
.then(function (postedFiles) {
dataObject.iconImg = postedFiles.body.payload.files[0].id;
dataObject.headerImg = postedFiles.body.payload.files[1].id;
//save dataObject after storing images and processing data
dataObject.save(function(savedDataObject){
next(success(req, 200, 'dataObject Saved ' + savedDataObject.id));
});
})
.catch(function(err){
console.log('FAILED: ', err.stack);
return next(failure(req, 500, err));
});
});
When I test my route with a separate small requestJS script, it works just fine:
HTTP rest api request test with requestJS
postDataObject.js
var request = require('request');
var fs = require('fs');
var uuid = require('uuid');
var formData = {
name: 'someName',
info: 'Some INFO and text description. ',
'usersArray[0][uuid]': uuid.v4().toString(),
'usersArray[1][uuid]': uuid.v4().toString(),
'usersArray[2][uuid]': uuid.v4().toString(),
// handle files
iconImg: fs.createReadStream('/var/tmp/img/iconImg.png'),
headerImg: fs.createReadStream('/var/tmp/img/headerImg.png')
};
request.post({url:'http://127.0.0.1:2233/api/postDataObject', formData: formData}, function (err, httpResponse, body) {
if (err) {
return console.error('failed:', err);
}
console.log('DataObject creation is successful! Server responded with:', body);
});
Now I'm writing the wrapper library for the fronted usage, when I use the same code in another context, it seems, that Multer handling req.files.headerImg.path is not working, it's undefined.
The code I use for wrapper library:
wrapper-lib.js
var request = require('request'),
URI = require('URIjs'),
fs = require('fs'),
uuid = require('uuid'),
path = require('path'),
Promise = require('bluebird'),
_ = require('lodash'),
DataObjectBindings.prototype.createDataObject = function (jsonRequestJSFormData) {
var self = this;
// this give the URL of the API to make requests to
return self.getAPIurlHelper().then(function (apiUrl) {
return new Promise(function (resolve, reject) {
request.post({url: apiUrl, form: jsonRequestJSFormData}, function (err, res, body) {
if (err) {
reject(err);
} else {
resolve({res: res, body: JSON.parse(body)});
};
}); //end of .post
}); // end of Promise
}); // end of getAPIurlHelper() function
}; // end of createDataObject function definition
And Finally I test the warpper with:
wrapper-test.js
// Instantiate Broker Client
var Wrapper = require('./wrapper-lib');
var wi; //wrapper instalnce
var ConnectApiRequestTracer = require('./connectApiRequestTracer');
var fs = require('fs');
ConnectApiRequestTracer().connect()
.then(function () {
wi = new Wrapper();
return wi.createDataObject(
uuid.v4(),
{
name: 'Some Cool Name',
info: 'Some nice description and info. ',
'usersArray[0][uuid]': uuid.v4().toString(),
'usersArray[1][uuid]': uuid.v4().toString(),
'usersArray[2][uuid]': uuid.v4().toString(),
iconImg: fs.createReadStream('/var/tmp/img/iconImg.png'),
headerImg: fs.createReadStream('/var/tmp/img/headerImg.png'),
);
})
.then(function (data) {
console.log('SUCCESS: ', data);
})
.catch(function (err) {
console.log('FAILED', err.stack);
});
When I run the test case wrapper-test.js, it throws me an error, that says the req.files.iconImg.path is undefined.
Any ideas what can be wrong?
try using :
req.file.iconImg.path
req.file.headerImg.path
instead of req.files.iconImg.path and req.files.headerImg.path
Please help me. I need variable in my search use post:
app.post('/find', function(req, res) {
var id_school = req.body.std_id;
console.log('show '+ id_sekolah);
db.collection('ak_test_score', function(err, collection) {
collection.find({'std_id':id_school}).toArray(function(err, level) {
var a = level.std_id;
var b = level.school_name;
});
});
res.redirect('/test_score'); // send to my page to get
};
var test = a; // not defined variable a not have
app.get('/test_score', function(req, res) {
var id_school = test;
console.log('show '+ id_sekolah);
db.collection('ak_test_score', function(err, collection) {
collection.find({'std_id':id_school}).toArray(function(err, level) {
res.send(level)
});
});
};
I am using this for a website search using post.
app.post('/find', function(req, res) {
var id_school = req.body.std_id;
console.log('show '+ id_sekolah);
db.collection('ak_test_score', function(err, collection) {
collection.find({'std_id':id_school}).toArray(function(err, level) {
var a = level.std_id;
app.set('data',a);
var b = level.school_name;
});
});
res.redirect('/test_score'); ///// send to my page to get
};
app.get('/test_score', function(req, res) {
var id_school = app.get('data');
console.log('show '+ id_sekolah);
db.collection('ak_test_score', function(err, collection) {
collection.find({'std_id':id_school}).toArray(function(err, level) {
res.send(level)
});
});
};