view not gathering data from service through controller

116 views Asked by At

Having trouble loading an external json file and having it's contents display on my view. I've included my view, controller and services code. What do I need to change?

view.html

<div ng-controller='BaseCtrl'>
    <table class="table table-hover">
        <tbody>
           <tr class="tr-sep" ng-repeat="example in examples" ng-click="showUser(example)">
              <td>{{example.name}}</td>
              <td>{{example.type}}</td>
              <td>{{example.size}}</td>
           </tr>
        </tbody>
    </table>
</div>

controller.js

'use strict';

angular.module('projyApp')
  .controller('BaseCtrl', function ($scope, data) {
    $scope.examples = data.getAllExamples();

    $scope.showUser = function(example) {
        window.location = '#/user/' +example.size;
    };

  });

service.js

'use strict';

angular.module('projyApp')
  .service('data', function data() {
        var examples;

        var getAllExamples = function () {

            $http.get("../../TestData/Examples.json").success($scope.examples = data.examples);
        };

  });
3

There are 3 answers

1
Michael Benford On BEST ANSWER

Your service code isn't correct. I see the following problems:

  • You're creating a local variable getAllExamples that's not accessible from outside the service;
  • You're using the $http service, but that dependency isn't expressed in the service constructor;
  • You're trying to update the scope from the service, but it's inaccessible from there. Plus, the $scope variable is not even defined inside the service code.

Here's how your service could look like:

.service('data', function($http) {
    this.getAllExamples = function(callback) {
        $http.get("../../TestData/Examples.json")
            .success(function(data) {
                if (callback) callback(data.examples);
            });
        };
});

And your controller code would be like this:

.controller('BaseCtrl', function ($scope, data) {
    data.getAllExamples(function(examples) {
        $scope.examples = examples;
    });

    $scope.showUser = function(example) {
        window.location = '#/user/' +example.size;
    };
});

You could ditch the callback in the getAllExamples function and work directly with the $http.getreturned promise, but that's a bit more complicated.

Update Added a Plunker script to illustrate the code above.

2
L105 On

You should use a callback instead of assigning in to a scope in you data service. By doing that, you can use this function in multiple controllers an assign values to appropriate scopes.

Data Service

  var getAllExamples = function (callback) {

            $http.get("../../TestData/Examples.json").success(function(data) {
                if (typeof callback === "function") callback(data);
            });
   };

Controller

data.getAllExemples(function(data) {
    $scope.examples = data;
});

EDIT

Another what is to create a promise object.

Data Service

  var getAllExamples = function () {

            return $http.get("../../TestData/Examples.json");
   };

Controller

var promise = data.getAllExemples();

promise.then(function(data) {
   $scope.examples = data;
});

EDIT 2

In your service, you need to return your functions

angular.module('projyApp')
  .service('data', function data() {
        var examples;

     return {
            getAllExamples: function () {

                 $http.get("../../TestData/Examples.json").success(...);

            }
};

  });
1
shaunhusain On

Main module definition should look like:

angular.module("projyApp",[/*dependencies go here*/]);

Service should look like

//this use of module function retrieves the module
//Note from comments in angular doc: This documentation should warn that "angular.module('myModule', [])" always creates a new module, but "angular.module('myModule')" always retrieves an existing reference.)
angular.module('projyApp')
  .service('dataService', [/*dependencies,*/function() {
        var service = {
            examples:[],
            getAllExamples = function () {

                $http.get("../../TestData/Examples.json").success(function(returnedData){examples = returnedData});
            }
       }
       return service;
  });

Controller should look like:

angular.module('projyApp')
  .controller('BaseCtrl', function ($scope, dataService) {
    $scope.examples = [];

    $scope.showUser = function(example) {
        window.location = '#/user/' +example.size;
    };
    $scope.$watch(function(){return dataService.examples}, function(newVal,oldVal) {$scope.examples = newVal});

  });

Also you can add

debugger;

on an line to trigger Chrome to break (like a breakpoint but without having to dig through the scripts at run-time) so long as the Debugging Panel is open (F12)