Question

I'm trying to add some basic CRUD functionality to MEAN stack. I've created a RESTful service that works and I'm confused about how to wire it all up. I can get it to work, but I want to make sure I'm doing things the best way and not creating an unnecessary hack.

My api route for a single Person is like this:

// Find one person
app.get('/api/person/:id', function(req, res) {
  Person.find ( {_id: req.params.id },
    function(err, data){
      res.json(data);
    }
  )});

 // Find group of people
 app.get('/api/person', function(req, res) {
   // use mongoose to get all people in the database
   Person.find(function(err, data) {
     res.json(data); 
 }); 

This seems to work in that if I go to a URI with an ID, as in localhost://3000/api/person/23423434, I see JSON data like this:

[
  {
    "_id": "532d8a97e443e72ef3cb3e60",
    "firstname": "Horace",
    "lastname": "Smith",
    "age": 33
  }
]

This tells me the basic mechanics of my RESTful api are working. Now I'd like to display that data with angular in a template like so:

<h3>{{ person.firstname + ' ' + person.lastname }} </h3>

To do that, I just need to create a $scope.person object with get() or query(). Here's the relevant part of my app:

angular.module('crudApp', ['ngRoute', 'ngResource'])
  .config(['$routeProvider', function($routeProvider){
    $routeProvider
      .when('/api/person/:id',
        {
          templateUrl: 'partials/person.html',
          controller: 'PersonCtrl'
        });
      }])
      .factory('Person', function($resource){
        return $resource('api/person/:id', { id: '@_id'});
      })
      .controller('PersonCtrl', function($scope, $routeParams, Person){
         $scope.person = Person.get( { id: $routeParams.id } ); // Having trouble here!
      });

The trouble I'm having is that get() fails with an error (Error: [$resource:badcfg]). On the other hand, if I use Person.query(), I get back an array, which means I need to change my template to the following:

<h3>{{ person[0].firstname + ' ' + person[0].lastname }} </h3>

This works, but seems strange and isn't like what I've seen in angular tutorials. The only other solution I've found is to set $scope.person in a callback:

Person.query({ id: $routeParams.id  }, function(person){
  $scope.person = person[0];
});

This works with my original unmodified template. Is it the best or right way to work with RESTful apis like this? Is there a better way?

Answer: the answer is in comment below. My problem is that api is using Person.find() but should be using Person.findOne( { _id: req.params.id }); Using findOne() returns a single object.

Was it helpful?

Solution

Your api should look like this:

route -> '/api/person/:id'
    return single person
route -> '/api/person'
    return array of persons

then if you want to get by id, you shall use get method, or if you want to get all persons, you should use query method. Your mistake is that you shall return single object when getting by id

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top