Reputation: 2471
I have a working NodeJS API using Express. I am confused how to properly pass in a parameter from NodeJS to AngularJS in order to retrieve the data for the page.
Note: My question is an extension (not a repeat) of this question: How do I pass node.js server variables into my angular/html view?
I have set up two routes, one to render the page and one to return the JSON object based on the Book ID (the unique ID of the entity). When the page loads, Angular uses $http to send a GET request to get the data from a JSON endpoint.
This is working, but I have hard-coded an example Book ID in Angular.
Question: How can I pass the Book ID to the Angular controller?
/*EXPRESS ROUTES*/
//Render page
router
.route('/detail/:book_id')
.get(ctrlRequest.detailPage);
//Return JSON data
router
.route('/detail/json/:book_id')
.get(ctrlRequest.detailJSON);
/*NODEJS CONTROLLERS*/
//Render page
module.exports.detailPage = function(req, res) {
res.render('transfer_request_detail.pug', {
title: 'Transfer Request Detail'
});
};
//Return JSON data
module.exports.detailJSON = function(req, res) {
getModel().read(req.params.book_id, (err, entity) => {
if (err) {
console.log('Request Detail JSON unable to return data results. Error message: ', err);
return;
} else {
res.json(entity);
}
});
};
/*ANGULAR WITH HARD-CODED BOOK ID*/
//QUESTION: HOW TO PASS THE BOOK ID IN DYNAMICALLY?
function DetailPageController($http) {
var vm = this;
$http({
url: '/detail/json/5761233819297931', //HARD-CODED ID HOW TO PASS IN DYNAMICALLY?
method: 'GET'
}).then(function (response){
vm.book = response.data;
console.log('API worked', response);
},function (error){
console.log('API error: ', error);
});
}
UPDATE:
"This probably depends on how your application is used. For example, the app might display a list of Books fetched from Express, and the user clicks one to see the detail page. In that case, the frontend fetches the complete list of Book ID's from Express. Can you please outline the behavior of your application?"
Use Case 1: After the user submits a the New Book form, the Node app will redirect to the URL that renders the detail page. '/detail/:book_id'. I want to use Angular to build a datatable to display the details of the book that was created.
Use Case 2: Another use case in the future will be to display all books that were created by the logged-in user. In this case, I want to use Angular to display all the books in a datatable. The route will be something like '/mybooks/:username'. Also, the user should also be able to click on a link that brings them to the details page (use case 1) for single book.
UPDATE 2:
I tried using routeParams to extract the ID out of the URL. It appears to be exactly what I need however it isn't working. Note that the routes were created on the server side with Express, not Angular.
$routeParams //Object
$routeParams.book_id //undefined
https://docs.angularjs.org/api/ngRoute/service/$routeParams
UPDATE 3:
I was able to solve this with a bit of a hacky workaround. I'm not super satisfied with this solution since it is quite hacky but at least it works for the time being.
I used this code in the Angular controller to extract the ID from the URL.
var relpath = $location.path().split('/');
var book_id = relpath[3];
UPDATE 4: So it looks like I am back to square one. This solution broke the express routing. I am now having the same issue as described in this thread because locationProvider HTML mode is enabled to get this solution to work. Pages aren't loading when clicking on menu links, they are only loading when typed in directly.
Angular routing doesn't work when URL is directly visited in browser but works when clicked to?
Upvotes: 1
Views: 417
Reputation: 114
You can use template literals: in your url string.
function DetailPageController($http, id = 5761233819297931) {
var vm = this;
$http({
url: `/detail/json/${id}`, //HARD-CODED ID HOW TO PASS IN DYNAMICALLY?
method: 'GET'
}).then(function (response){
vm.book = response.data;
console.log('API worked', response);
},function (error){
console.log('API error: ', error);
});
}
Upvotes: 1