I am in the process of converting one of my sites (http://maskedarmory.com) from LAMP (using Laravel 4 MVC) over to the MEAN stack and it has been quite a journey thus far.
I have managed to get the landing page up and running and the input POSTing to Angular controller that I have it routed to.
Now, the problem I am having is getting the service to send over the POSTed data that is in Angular over to the Express API. I keep keeping a 404 Not Found error on the /api/character URL path.
Also, how do I access the 'characterData' variable that is on the Angular side that is being passed over by the factory? Because I am trying to do a console.log on the 'characterData' variable on the server side and I am sure that that is out of scope.
app/routes.js (Express Routing)
// public/js/services/ArmoryService.js
angular.module('ArmoryService', []).
factory('Armory', function($http) {
return {
// Get the specified character by its profile ID.
get : function(id) {
return $http.get('/api/character/' + id);
},
// call to POST and create a new character armory.
create : function(characterData) {
return $http.post('/api/character', characterData);
}
}
});
app/routes.js (Express Routing)
module.exports = function(app) {
app.post('/api/character', function(req, res) {
console.log(characterData);
});
app.get('/', function(req, res) {
res.sendfile('./public/index.html'); // load our public/index.html file
});
};
If I do a console.log before the $http.post to the API, 'characterData' has all of the information it should.
I am sure that this is a routing issue of some type, but I will be damned if I can figure it out.
Thanks in advance for your help!
Try this:
app.post('/api/character', function(req, res) {
console.log(JSON.stringify(req.body));
res.status(200).send('whatever you want to send back to angular side');
});
app.get('/api/character/:id', function(req, res) {
console.log(req.params.id);
res.status(200).send('whatever you want to send back to angular side'');
});
Related
First of all, i'm using JetBrains WebStorm and used to create the Node.js Express App project.
My modifications were at app.js
app.get('/api/restaurants', function(req, res) {
console.log("Parameter[0]", req.params.restaurant_id);
res.json({
'01010112D8139F13': '0ao123r1'
});
});
app.get('/api/restaurants/:id', function(req, res) {
console.log("Parameter[1]", req.params.restaurant_id);
res.json({
'message': 'worked?'
});
});
I'm using postman plugin at chrome to test my api and i can't access localhost:3000/api/restaurants?restaurant_id=01010112D8139F13 without being routed by router.route('/restaurants') instead of router.route('/restaurants/:restaurant_id')
At console i have:
GET /api/restaurants?id=01010112D8139F13 200 1.803 ms - 31
If anyone can help me, thanks in advance.
restaurant_id is not a query parameter but a variable part in your path. For example /restaurants/01010112 and /restaurants/1 are both handled by the same Web request handler because both fit on /restaurants/:restaurant_id pattern.
The restaurant specific endpoint need to be modified the following way:
app.get('/api/restaurants/:id', function(req, res) {
console.log("Parameter[1]", req.params.id);
res.json({
'message': 'worked?'
});
});
And use the following url on the console:
/api/restaurants/01010112D8139F13
Okay here's the scenario, to my knowledge there are three ways to create a web application
Traditional way: Render the HTML page from the server
Not sure: Create an API and let the user's browser to download the
Javascript application (Angular, React, Ember) to get a highly
interactive application
The future: Isomorphic web app, which render the HTML together with the client-side technologies (Angular, React, Ember) from the server.
I'm planning to use the third way, due to faster load page, but the problem right now is if I were about to create a mobile application.
My stack: Node.js + React
Let say if I'm planning to go mobile, do i need to duplicate the same route and logic ?
Current problem
app.get('/users', function(req, res) {
res.render('index', { message: "Hey Im Jack" });
});
app.get('/api/users', function(req, res) {
res.json({ message: "Hey Im Jack" })
});
Is there any way that I could use to for one route to serve both the HTML and REST?
You can ultimately only send either HTML or JSON (in case of REST).
The /api/xxx route syntax makes it clearer which path serves the JSON.
But you can depend on client's request header to check whether they requested JSON or HTML
app.get('/users', function(req, res) {
if (req.headers.accept && req.headers.accept.match(/json/))
res.json(data);
else
res.render('index', data);
});
Angular's $http usually requests json by default, not sure about others, but you can set the headers. Browsers normally request text/html, but I'm not sure.
Or if you're only concerned about not having to repeat the logic that fetches the data, you could put a middleware preceeding both:
// regex to match both routes
app.get(/.*users/, function(req, res) {
res.locals.data = { message: "Hey Im Jack" };
req.next();
});
app.get('/users', function(req, res) {
res.render('index', res.locals.data);
});
app.get('/api/users', function(req, res) {
res.json(res.locals.data)
});
I'm using MEAN stack with MeanJs. The thing is, I have a task that requires calling a GET request from the server side (Expressjs) to another server (with a different domain name).
The code in the client side (AngularJs) calls:
$scope.getWorkflow = function() {
$http.get('/ezee', $scope.credentials).success(function(response) {
console.log(response.message);
}).error(function(response) {
console.log('error');
});
};
And the corresponding server controller function is:
exports.list = function(req, res) {
req.get('http://ezslave.io', function(q, r){
res.json({message: r.message}); // just to test
});
};
Obviously, the code below doesn't work. I'm unsure about how to make a GET request from that list function. Am I supposed to use ExpressJs or pure NodeJs for this? And how to get the correct library loaded?
Use the request module of nodejs : https://github.com/mikeal/request
for sending the http request.
var request = require("request");
exports.list = function(req, res) {
request("http://ezslave.io",function(err,response,body){
res.send(response);
});
};
Hope this helps you
I have several "api" endpoints in my application that are used by the front-end framework for its AJAX processes. For organizational purposes, I would like to re-use the code for these endpoints to retrieve data for server-side rendering, which I do in some instances to play nicely with search engines. So, ideally I would implement some sort of HMVC setup to simply access a route on the API endpoint. Specifically I would like to get the response and perform additional actions on it before issuing the top-level response (e.g., render a view with results).
For example:
app.get('/post/recent', function(req, res) {
app.doRequest('/api/posts/', req, function(res2) {
var data = res2.body;
res.render('posts/index', data);
});
});
What's the best way to do this?
So far the best option I've come up with is:
Expose all logic in an endpoint as a method, which would be used in app.get('...', myFunction), and then I could call myFunction elsewhere outside of the express flow for that path. However, this would not give me a reliable way to run middleware specific to the endpoint (which I would also want to run on the HMVC request) unless I wrote my own middleware implementation that did not rely on express. The API endpoint has middleware that does something like if(!hasAccess) res.send(403), which I specifically do NOT want to happen in my main route since I'd want to render a nice error page instead of just sending an error code.
Example:
var getPosts = function(req) {
var deferred = q.defer()
doDatabaseQuery(req.query).then(function(response) {
deferred.resolve(response)
});
};
app.get('/api/posts', myMiddlewareFunction(), function(req, res) {
getPosts(req).then(function(response) {
res.send(response);
});
);
app.get('/post/recent', function(req, res) {
// I want to run middleware here, not in root level
getPosts(req).then(function(response) {
res.render('post/index', response);
}, function(err) {
res.render('error/noaccess');
});
});
Any better ideas? Is there a way to programmatically access an express route and get the result?
I figured this out by diving into the Express source code. There is a method called handle which I can manually invoke with modified request and response objects to get the effect I want:
app.get '/posts', (req, res) ->
req.url = '/api/posts'
newRes = _.clone(res)
newRes.send = (data, code)->
if code is 200
return res.render('posts/index', data)
else
return res.render('error')
app.handle(req, newRes)
I am using an AngularJS Resource to make an ajax post to a node js server running express. However I am unable to access the post payload parameters on the NodeJS side.
I have a service set up:
angular.module('app.services', ['ngResource'])
.factory('PostService', function($resource) {
return $resource('/postTest');
});
and in the controller I have:
function UserCtrl($scope, PostService) {
//query for the users
$scope.testPost = function() {
var stuff = {firstname: 'some', lastname:'person'};
PostService.save(stuff,function(data) {
console.log('called save on PostService');
});
};
}
I can see the payload inside of the http header:
{"firstname":"some","lastname":"person"}
however, when I get to the NodeJS route to process it, I am not sure how to access the parameters:
(output from node console): inside test stuff
req.params undefined
app.post('/postTest', function(req, res) {
console.log('inside test stuff');
console.log('req.params ' + req.param('stuff'));
})
I have created a fiddle at: http://jsfiddle.net/binarygiant/QNqRj/
Can anyone explain how to access the parameters passed by the post in my NodeJS route?
Thanks in advance
If "{"firstname":"some","lastname":"person"}" is in the body of the post in json?
You'd access it differently.
Using express.bodyParser(), req.body.firstname will get you the firstname
app.use(express.bodyParser());
Then
app.post('/postTest', function(req, res) {
console.log('inside test stuff');
console.log(req.body.firstname);
})
You need to set body parser in your App
for example in ExpressJs 4,
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));