How to create RestFull api with express and node.js? - angularjs

I am very new to node and express i read some documentation but i did not get any solid understanding how to create rest api with node, So with below basic code i just want to create get api with express and return response to angularjs factory method.I would like to get help and better understanding for the following .
1- How to return response with GET api ?
2- If we have json object how can i pass that data using GET api ?
app.js
var express = require('express');
var path = require('path');
var app = express();
app.use(express.static('./'));
var server = app.listen(3000, function(){
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http',host,port);
});
app.get('/test', function(req, res) {
res.type('text/plain'); // set content-type
res.send('i am a beautiful butterfly'); // send text response
});
workerController.js
$scope.getTestData = function(){
alert('got function working');
workerFactory.getData().then(function(response){
var dataResponse = response.data;
console.log(dataResponse);
})
}
workerFactory.js
angular.module('myApp').factory('workerFactory', function ($http) {
'use strict';
return {
getData: function(){
return $http.get('/test');
}
}
});

For the second part, how to pass a JSON object back. You can change your API code to something like:
app.get('/test', function(req, res) {
res.json({message: 'i am a beautiful butterfly'}); // send a JSON response
});
I'm just working on the first part of the question

You can get a full working REST-full API code by using Amplication, it's an open-source for generating Node.js code by only defining your data model.

As you have the basic understanding on REST API you can use this node module
https://github.com/swagger-api/swagger-node for creating great REST API.

Related

socket.io emit not working properly inside express route

I use soket.io in Node.js it's working fine, but there is an issue in the routes files.
Below is my code and flow.
I have server.js file where I define io.
var express = require('express'),
app = express(),
http = require('http').Server(app);
var io = require('socket.io').listen(http);
//io from server.js
io.on('connection', function (socket) {
socket.emit('getDevicePostData', { message : 'Hi from server!!' });
socket.on('sendDevicePostData', function("Hi from server") {});
});
// pass io to routes file
var smart_control = require('./smart_control.js')(io);
app.use('/', smart_control);
And smart_control.js file code is below
module.exports = function(io) {
router.post('/emitdata', function(req, res, next) {
io.sockets.emit('getDevicePostData', { message : 'Hi from route!!' });
});
return router;
}
Above route's emit sometimes work and sometimes does not work.
And this emit is called from angular js. I use https://www.npmjs.com/package/angular-socket-io package in angular
Below code in angular controller:
mySocket.on('getDevicePostData', function(data) {
console.log(data);
});
Here mySocket is factory.
What is wrong in my code. Mainly problem from routes file only.
You just need to replace io.sockets.emit with io.emit.
Here io.sockets.emit will emit to only connected clients and your socket factory might not be up by the time you hit the API.

Post SQL data to Angular View with NodeJS

I'm having a difficult time posting data retrieved from a server using mysql with node. I have connected to my db successfully, and I can return the data I want by console logging it to the CLI when running "node server.js". However, I'm not sure how to post this data to my Angular view. No problem console logging, but this doesn't help me get data to the application.
For the moment, I'm just trying to get the data to index.html, which is my primary view and holds my ng-view portion for Angular routing. I'm probably missing something obvious bc I'm new to NodeJS.
// MODULES
var express = require('express');
var app = express();
var port = process.env.PORT || 3000;
var mysql = require('mysql');
var serveStatic = require('serve-static');
var bodyParser = require('body-parser');
var source = __dirname + '/public/views/index.html';
app.use(serveStatic(__dirname, {'index': ['index.html']}));
app.route('/*')
.get(function(req, res) {
res.sendFile(source);
});
var data;
var connection = mysql.createConnection({
host : 'thehostdb',
user : 'username', // credentials correct, connection works
password : 'pw',
database : 'db',
port: '3306'
});
connection.query('SELECT * from poemTable', function(err, rows, fields) {
if (!err) {
data = JSON.stringify(rows);
setDataValue(data);
}
else {
console.log('Error while performing Query:', err);
}
});
function setDataValue(value) {
data = value;
console.log(data); //Where the data logs
}
app.listen(port, function () {
console.log('Example app listening on port' + port + '!')
})
You have to understand what this code does, and how nodejs and angular are supposed to work together. Angular is served to the client and then rendered by the clients browser. So if you want to inject data you have to fetch it. So in your angular app when the controller starts make an api call, and in your server create a new route:
app.get('/data', function(req, res, next) {
connection.query(..., function(err, rows, fields) {
res.json(rows);
});
});
Make sure you understand node and it's async nature, what is event loop and how it works and what is callback hell, also I would check out promises and other tutorials on nodeschool.io, it's a great place to start with node :)

Passing External API to Angularjs

I'm working with an external API from Shipstation. I can do a GET request to pull the information in just fine into Nodejs, but I can't figure out how I can transfer that data client-side to manipulate within Angular? I've been struggling with this for a few days now and all my googling searching isn't helping out.
server.js
var express = require('express');
var request = require('request');
var app = express();
app.use(express.static('public'));
var Orders = require('./controllers/ordersController');
app.use('/orders', Orders);
app.listen(3000, function() {
console.log('I am live on port 3000');
});
ordersController.js
var request = require('request');
module.export = request({
method: 'GET',
url: 'https://ssapi.shipstation.com/orders/listbytag?orderStatus=awaiting_shipment&tagId=32099&page=1&pageSize=100',
headers: {
'Authorization': 'xxxxxxxxxxx'
}}, function (error, response, body) {
console.log('Status:', response.statusCode);
console.log('Headers:', JSON.stringify(response.headers));
console.log('Response:', body);
});
I figured the best way was to put the GET request in its own "orders" module, export it, and then have angular access that route in an http request (/orders). Sounds good in theory, right?
I appreciate the help in advance! Thanks guys!
I'm assuming that the ShipStation API provides JSON which is easily consumable by Angular.
You can load the JSON into your Angular app like this:
$http.get('/orders:3000', function(data) {
$scope.Orders = data;
console.log($scope.Orders);
});
Add this to your controller, then check the browser's developer console to see the output. From there, you can manipulate the JSON object however you need and display the information in your HTML view.

How to retrieve response from server using angularjs?

I am sending filename to server and trying to get some sort of response to make sure api calls are working but its always returing 404 even though path is correct, I am not sure where i am making mistake , Any idea ?
angularjsFactory.js
getFile:function(file_name){
return $http.get("/file?file_name="+file_name);
}
server.js
var express = require('express');
var app = express();
var fs = require('fs');
app.use(express.static(__dirname + "/public"));
var readDirectory = require('./readDirectory');
app.get('/file', function(req, res) {
var path = './ditLogs';
var fileParam = req.query.file_name;
console.log(fileParam);
fs.readdir(path, function(err, items) {
items.forEach(function(items) {
if (fileParam === items) {
res.sendFile(items);
console.log(items);
}
});
});
});
app.listen(3000, function() {
console.log('Example app listening on port 3000!');
//console.log('app is printing data',obj);
//ditProducer.startProducer();
setTimeout(function() {
ditconsumer.start();
}, 2000);
});
Your route on server is not correct comparing to the call from angular's side. You are not using route parameters, but query string.
Try this:
app.get('/file', function (req, res) {
// get filename using: req.query.file_name
res.send('FIle data');
});
Or you can try this on angular and keep the server code:
$http.get("/file/"+ encodeURI(file_name));
Server side code looks incorrect.
app.get('/file', function (req, res) {
console.log(req.query.file_name);//This will give you filename passed as url param
res.send('FIle data');
});

How to pass multiple parameters in a URL Angular/REST API

I'm trying to pass multiple parameters in a URL with no luck. I'm not sure if it makes a difference but I am doing it through Angular. I'm trying to send the request to a REST API backend that I know works for single requests. Here is what my backend looks like
index.js
var express = require('express');
var router = express.Router();
var game = require('./game');
router.get('/api/v1/gameRefined/:from_datepicker:to_datepicker:from_timepicker:to_timepicker:selectLevel', game.getAllRefined);
module.exports = router;
game.js
...dbconnection stuff...
var game={
getAllRefined: function(req, res) {
var refines = req.params;
console.log("getting refined games");
pool.getConnection(function(err, connection){
var query = connection.query('SELECT * FROM game WHERE date >= ? AND date <= ? AND time >= ? AND time <= ? and level = ?', [refines.from_datepicker, refines.to_datepicker, refines.from_timepicker, refines.to_timepicker, refines.selectLevel], function(err, rows) {
connection.release();
if(err) {
throw err;
}else{
res.json(rows);
}
});
})
},
}
module.exports = game;
I send the request from this factory
.factory('gameFactory', ['$http',
function($http) {
var _gameFactory = {};
_gameFactory.getRefinedGames = function(dateFrom,dateTo,timeFrom,timeTo,level) {
var encodedParam = encodeURIComponent(baseUrl + '/api/v1/gameRefined/?from_datepicker='+dateFrom+'&to_datepicker='+dateTo+'&from_timepicker='+timeFrom+'&to_timepicker='+timeTo+'&selectLevel='+level+'');
return $http.get(encodedParam);
}
return _gameFactory;
}])
That sends this request that comes back as a 404:
http://localhost:8100/http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fv1%2FgameRefined%2F%3Ffrom_datepicker%3D2015-02-05%26to_datepicker%3D2015-02-19%26from_timepicker%3D12%3A00%26to_timepicker%3D18%3A00%26selectLevel%3D1
I have tried it encoded and not encoded, with forward slashs, with semi colons, but nothing has worked so far.
I don't know why a localhost gets appended at the start, but even trying it in postman without the first localhost still is a 404 error.
How should I be doing this? Any help is appreciated. Thank you.
First, other than separating the work into a factory, you aren't really using Angular here. Second, I would consider posting to your API, return JSON results from the API, and then use a promise to read the data back into Angular.
Use $http.post
Let Angular do this work for you. Something like the below will generate the URL request for you. The return value of $http is also a promise, so using .success and .error will allow you to parse any returned data as well, even if it is just a success or failure message - but it is a great method of passing data between server/API and client.
.factory('gameFactory', ['$http',
function($http) {
return {
reachAPI: function(dateFrom, dateTo) {
$http.post('http://localhost:8080/api/v1', {
'dateFrom': dateFrom,
'dateTo': dateTo
})
.success(function(data, status, headers, config) {
*things happen*
data.somethingReturned // from your API
});
}
}]);
Consider body-parser
I know you said you have confidence in your REST API structure, but body-parser is an Express middleware that can parse URL-encoded strings and may prove helpful in reading your data. Personally, I think it lends towards more readable code.
var app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
router.route('/api').post(function(req, res) {
*things happen*
req.body.dateFrom //find your data
*things happen*
res.json(returnedData);
});
Hope that helps

Resources