1

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?

pengz
  • 2,279
  • 3
  • 48
  • 91
  • 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? – ContinuousLoad Oct 12 '17 at 16:25

1 Answers1

1

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);
});

}

Jay Hamilton
  • 114
  • 5
  • Ok great! But, how do I pass in the ID into DetailPageController when it is called? – pengz Oct 12 '17 at 17:14
  • that depends on where the id is located to begin with. Is it user input? You will need to pass it into the DetailPageController function when you call it. At what point do you have the Id? – Jay Hamilton Oct 12 '17 at 17:26
  • The ID is generated by the database so they won't be typing it in. Basic use case: 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. I just can't find a way to pass the book ID into the Angular controller from the Express route. – pengz Oct 12 '17 at 17:32
  • I am taking a look at routeParams now. I'm trying to use that to extract the ID from the URL. It isn't working so far but I'll keep digging, hopefully I am on the right track. https://docs.angularjs.org/api/ngRoute/service/$routeParams – pengz Oct 12 '17 at 18:10
  • 1
    Ok. You can parse the id off of the the url with $location provider. $location.path() will contain a string of the url. Then you could split('/') it into an array and then pop() off the last index , which should be the id. – Jay Hamilton Oct 12 '17 at 19:29
  • Thanks! Yes that is what I ended up doing basically. It seems kinda hacky to me but at least it works for the time being. var relpath = $location.path().split('/'); var book_id = relpath[3]; – pengz Oct 12 '17 at 19:38
  • Looks like I am back to square one, as this solution is causing issues with express routing. Pages aren't loading when clicking on menu links, they are only loading when typed in directly. This is because locationProvider HTML mode is enabled. https://stackoverflow.com/questions/20459047/angular-routing-doesnt-work-when-url-is-directly-visited-in-browser-but-works-w – pengz Oct 13 '17 at 19:27