Stef
Stef

Reputation: 369

Trying to access json-server data via a controller and factory in angular

I'm writing a very simple test app in angular js and am trying to display data stored on a json server to display in the view.

db.json is as follows:

{
  "examples": [
    {
      "id": 0,
      "name": "example 0",
      "description": "Example 0 description."
    },
    {
      "id": 1,
      "name": "example 1",
      "description": "Example 1 description."
    }
  ]
}

controller is as follows:

angular.module('my_app')

.controller('ExampleController', ['$scope', 'exampleFactory', function ($scope, exampleFactory) {

    $scope.example = exampleFactory.query({
        })
        .$promise.then(
            function (response) {
                var examples = response;
                $scope.message = examples;
            },
            function (response) {
                $scope.message = "Error: " + response.status + " " + response.statusText;
            }
        );

}])

factory is as follows:

.factory('exampleFactory', ['$resource', 'baseURL', function ($resource, baseURL) {

        return $resource(baseURL + "examples/:id", null, {
            'update': {
                method: 'PUT'
            }
        });
}])
;

And view is as follows:

<p>Test outside repeat: {{message}}</p>

<ul>
   <li ng-repeat="example in examples">
       <p>Test in repeat: {{message}}</p>
       <p>{{example.name}}</p>
       <p>{{example.description}}</p>
    </li>
 </ul>

The interesting thing here is that the data is being returned by the factory. In the above example the first test (outside the ng-repeat) returns the full set. However, nothing inside ng-repeat shows up.

I've got this working using a slightly different arrangement using a service but it doesn;t seem to be working using a factory.

Does anyone have any idea why this is and could they put me right?

Thanks Stef

Upvotes: 0

Views: 149

Answers (3)

Stef
Stef

Reputation: 369

Eventually sorted it by changing controller as follows:

.controller("ExampleController", function($scope, exampleFactory) {
  exampleFactory.query(function(response) {
      $scope.examples = response;

      $scope.examples.$promise.then(
          function (response) {
              var examples = response;
              $scope.message = examples;
          },
          function (response) {
              $scope.message = "Error: " + response.status + " " + response.statusText;
          }
      );

  });
});

Probably a little bit clunky and it would be nice to be able to reduce it further but as I'm very new to all this I'll go with this for now.

Upvotes: 0

alphapilgrim
alphapilgrim

Reputation: 3975

I'd suggest using a factory as you can get the methods inside the factory before the factory has been returned. It's the revealing module pattern, good read here if your interested JavaScript Design Patterns

angular
  .module('my_app')
  .controller('ExampleController', ['$scope', 'exampleFactory',
    function($scope, exampleFactory) {
      function getMessageList() {
        exampleFactory
          .getMessages()
          .then(function(messages) {
            $scope.examples = messages;
          })
          .catch(function(response) {
            $scope.message = "Error: " + response.status + " " + response.statusText;
          });
      }
      getMessageList();

    }
  ])
  .factory('exampleFactory', ['$http', 'baseURL',function($http, baseURL) {
      function getMessages() {
        return $http
          .get(baseURL)
          .then(function(jsonResp) {
            return jsonResp.data;
          })
          .catch(function(error) {
            //handle error if needed
            console.log(error);
          });
      }
      return {
        getMessages: getMessages
      };
    }
  ]);
<p>Test outside repeat: {{examples}}</p>

<ul>
  <li ng-repeat="example in examples">
    <p>Test in repeat: {{message}}</p>
    <p>{{example.name}}</p>
    <p>{{example.description}}</p>
  </li>
</ul>

Upvotes: 1

2ps
2ps

Reputation: 15926

I think you just forgot to assign $scope.examples, so the ng-repeat had no data to loop over:

angular.module('my_app')

.controller('ExampleController', ['$scope', 'exampleFactory', function ($scope, exampleFactory) {

    $scope.example = exampleFactory.query({
        })
        .$promise.then(
            function (response) {
                var examples = response;
                $scope.message = examples;
                $scope.examples = examples.examples; // I may be reading the JSON wrong here.
            },
            function (response) {
                $scope.message = "Error: " + response.status + " " + response.statusText;
            }
        );

}])

Upvotes: 2

Related Questions