Use node js as backend for ionic framework - angularjs

I followed the following tutorial to create a RESTApi for my node server...https://scotch.io/tutorials/build-a-restful-api-using-node-and-express-4
My server file now has routes that allow it to to make GET and POST requests which I've tested on Postman and they work. My server file is pretty long but here is an excerpt to get an idea of how it works...
router.route('/bears')
// create a bear (accessed at POST http://localhost:8080/api/bears)
.post(function(req, res) {
var bear = new Bear(); // create a new instance of the Bear model
bear.name = req.body.name; // set the bears name (comes from the request)
// save the bear and check for errors
bear.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Bear created!' });
});
})
.get(function(req, res) {
Bear.find(function(err, bears) {
if (err)
res.send(err);
res.json(bears);
});
});
router.route('/bears/:bear_id')
// get the bear with that id (accessed at GET http://localhost:8080/api/bears/:bear_id)
.get(function(req, res) {
Bear.findById(req.params.bear_id, function(err, bear) {
if (err)
res.send(err);
res.json(bear);
});
});
...etc,etc
Now, since I am using an ionic framework I need to configure it to use this server as a backend.
My problem is, how do I connect to it using angular?
All my routes are prefixed using /api
app.use('/api', router);
So I tried the following...
app.factory('Bear', function ($resource) {
return $resource('http://XXX.XXX.X.XX:3000/api/bears/:bearId');
});
But I'm not sure this is working. I want to make one Post request so that I can test that the backend is working but I do not know what code to add to do so.
For example, if I have a form on my index.html and I send this info to my angular controller, how can my controller take this info and make a post request to my server? I've been trying to figure this out for days.

If you just want to test that your backend is working, check out postman.
Here's how you can refactor your code. First, note that as it is currently, how you're using $resource isn't actually make any calls to the API. You should inject your Bear service in a controller or another service somewhere in your app, depending on how you're going to use the bears. Then, in this other service or controller, you would do
var result = Bear.get({ bearId: <value> }) or var result = Bear.post({ bearId: <value> })
or whatever other http method you want to use. The resource object will then automatically hit the URL endpoint with the specified HTTP action and the parameter you have provided and then return you back the result.
Check out the $resource documentation for more detail. Also, the fact that you're using ionic has no bearing on connecting to the API.

Related

How to communicate AngularJS's $http routes and APIs developed in C Programming

I have made web application GUI using AngularJS, Bootstrap, HTML, CSS.
Backend team are developing APIs in C Programing.
So how my routes in $http request (sending from factory) will communicate to C Programing API (Controller) to get data or to perform related operations.
Thanks!
You would just need the URI and the Async request would look like this:
$http.get('URI goes here').then(
function (response) {
//success
vm.data = response;
},
function (response) {
//fail
console.log("error");
}
);
I think you need to learn the concepts of Web API's. Basically the server (C written in your case?) responds to various HTTP requests (GET, POST, PUT, etc..). By defining a Web API you simply state that for some http request for a specific path - there's gonna be a meaningful response.
For example here's a Web API:
GET /api/users - list users
GET /api/users/{id} - get a specific user
POST /api/users/{id} - update specific user
To consume this endpoint (/api/users) you can use $resource or $http like so:
var UserFactory = $resource('/api/users/:id');
var userlist = UserFactory.query();
var user = UserFactory.get({id: 123});
user.$promise.then(function(){
user.balance = 100000000;
user.$save();
});
Basically in the background angular translates $resource calls to HTTP requests.

angular ngresource can't send headers

I'm new to the angularjs/ionic mobile app development. I'm using Parse REST api to store data and already hosted Parse server in Heroku. Tested with postman chrome extension and everything working fine. The problem that i'm facing right now is my angular-resource seem look like not sending any headers used to authenticate with parse to the server.
angular.module('starter.services', ['ngResource']).factory('Session', function ($resource) {
return $resource('/restapiurl', {}, {
get: {
method:'GET',
headers:{'X-Parse-Application-Id':'XXX', 'X-Parse-REST-API-Key':'XXX'}
}
});
});
Need an advice/guide to make my code work perfectly. Any help would be appreciate. Thanks in advance
UPDATE: I'm managed to send custom headers to the server. The workaround is to use $httpProvider.defaults.headers.common with the key and value inside module.config

How to set up node socket connection and access with REST

I want to have a route on my sailsjs node server that is a socket connection. I want to then send a rest request to that route from outside the app and have the socket hear the event and update the UI of my app.
So far all I have seen on the web is to have a websocket server by itself. Is there no way to integrate it into an existing server?
I'm a bit lost here. Can anyone point me to a tutorial that is doing this?
Question: How do I send a rest request to my server from outside the app and have the server update the UI of my app?
If you need more clarity here, please let me know.
You Have to use WebSockets I think. The UI does not know anything about the server unless it is notified. The only other way to have it running without WebSockets is to have a long polling AJAX request, but that solution would work for a limited use cases.
Adding a Socket.io server to a node server is pretty trivial, I would give it a try.
Use socket.io, it can be added to every Node.js server. For example:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs');
app.listen( 80 );
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(data);
});
}
io.set('log level', 1);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
You can use any socket event here.

Express Server, calling state.go and running a method in Controller

I am currently running an express server express.js with an angular js app. I use the UI router https://github.com/angular-ui/ui-router with stateprovider and state.go.
I have a requirement to allow a url to be typed in the browser
/getEmployeeDetails/1234
Am i going along the right lines , in that the following code can be added to the express server.js to achieve this or should I be handling this in the angular app states.
app.get('/p/:empId', function(req, res) {
controller.getEmpDetaails(req.params.empId);
state.go("employeeDetailsview")
});
I am not sure what was the reason for writing angular code inside your Express server but you should really separate your client code from your server code.
I assume you are trying to get some employee details by ID from your server.
The way it is usually done is by sending a HTTP request with the ID number from your client to the server. Then, the server will process the HTTP request (Maybe get some data from the database) and return a HTTP response to the client. And then the client will process the response and do something with it.
In your client yo can do something like this:
$http.post('SERVER_URL/getEmployeeDetails/', {'id': 1234})
.then(function(response){
// Response.data will have the data returned from the server
// Do something with it. for example, go to other state and pass the data to it
state.go("employeeDetailsview", {'employee': response.data});
});
The above will request an employee with id 1234 and do something with it.
In the server side:
app.post('getEmployeeDetails/', function(req, res) {
var employeeId = req.body.id; // YOU SHOULD USE THE BODY-PARSER MODULE IN ORDER FOR THIS TO WORK.
....
// Do something with ID
....
// Return some data to the client - for example an employee object
res.status(200).json({'data': employeeObject});
});

Node.js and Angular routing - How to make REST API inaccessible by browser URL

I use Angulars $http service to call for data on the backend. Let's say JSON data. An example URL to do so would be something like:
/get/data
Doing this from within Angular nicely returns the requested data. No problem.
But even though I catch all other Angular routes using Angular UI Router with $urlRouterProvider.otherwise('/');, I can still go to my browser and type in the mydomain.com/get/data URL, which provides me with a page of JSON code.
How to I restrict back-end server calls to come just from Angular, NOT from my browser URL without user authentication?
N.B.
Using Express 4.X on Node, I also provided my app with a 'catch-all' route to default back to my front-end index.html page, like so:
router.get('*', function(req, res) {
res.sendFile(path.join(__dirname, '/index.html'));
});
Thanks!
My God! Spent whole frikin day fighting this problem, finally fixed it!
The dog is burried in headers - you have to specify one on Angular http request, then read it in node.
First of - routing setup is the same as in this guide: https://scotch.io/tutorials/setting-up-a-mean-stack-single-page-application
On frontend in Angular http request I specify one of the accepted header types to be json:
$http.get('/blog/article', {
headers: {
'Accept': 'application/json;'
}
}).success(function(data) {
console.log(data);
})
.error(function(data) {
console.log('Error: ' + data);
});
On backend in Node I check if header includes json type. If it does, I serve back json data, so angular can receive the content. If it doesn't, I force node to load index.html, from which the controller runs the before mentioned http request with the header, ensuring you get your data then.
app.get('/blog/article', function(req, res) {
if(/application\/json;/.test(req.get('accept'))) {
//respond json
//console.log("serving json data...");
blogItemModel.find({ "_id" : req.query.id }, 'title full_text publish_date', function(err, blog_item){
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (err) res.send(err);
res.json(blog_item);
});
} else {
//respond in html
//console.log('Request made from browser adress bar, not through Angular, serving index page...');
res.sendfile('./public/views/index.html');
}
});
Agree with #HankScorpio
Angular UI routing for Angular application paths and server application accessing URL paths are two different things.
Angular UI router allows you to navigate within a single page application as if you have a multi page application. This is in no way similar to accessing the actual server application endpoint.
All restrictions should be done on the web server and server web application end. Hence you will have to implement some authentication/authorisation strategy.
This isn't really an angular issue. When a user enters mydomain.com/get/data they never actually load up the angular app, so your solution must be done elsewhere.
For example, you could add this to your website's .htaccess file. It will redirect all traffic to the root of your domain.
Check out this answer here:
.htaccess Redirect based on HTTP_REFERER
You can't.
Your angular code is running on their machine, in their browser.
As such, one can spoof the environment, capture the data as the browser requests it, edit the JS of your app while it is in their browser, or various other methods.
Why do you want such a restriction anyway?

Resources