0

Please bear with me. I'm very new to Angular—in fact only a day or so—but most of it makes sense to me. I've created Controllers, routes, etc. but putting it together I'm a bit lost.

My problem

I have a page with ng-view, and depending on the route different controllers are called with different data and templates. At the moment I have a "list" page and a "detail" page routing via an ID, but I need the list on both pages.

I read about using a factory and passing data one to the other, but is this the correct way?

plopApp.controller('juryCtrl', function($scope, $http) {
$http.get('/assets/javascripts/plop/plop/plopies.json').success(function(data) {
    $scope.plopies = data;
});
});

plopApp.controller('plopDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
    $http.get('/assets/javascripts/plop/plop/' + $routeParams._id + '.json').success(function(data) {
    $scope.plopor = data;
});
}]);

On the detail page, I want the list to be output as well. Do I do this using a factory, or have I structured the templates incorrectly?

UPDATE

I'm getting there - I understand the basics of the factories/services now, watched a video or two but am stuck on the execution for the detail page..

This is the factory Ive got working in my app

juryApp.factory('juryListFactory', function ( $http ) {
return {
    list: function() {
        return $http.get('/assets/javascripts/jury/jury/juries.json')
        .then(
            function(result) {
                return result.data;
        });
    }
};
});

and now im trying to convert the inside of this controller:

 juryApp.controller('juryDetailCtrl', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
    $http.get('/assets/javascripts/jury/jury/' + $routeParams._id + '.json').success(function(data) {
    $scope.juror = data;
});
 }]);

to a factory.. currently I wrote this but it doesnt seem to work

 juryApp.factory('juryListDetailFactory', '$routeParams', function($http, $routeParam){
var factory = {};
factory.getList = function(list, callback){
    $http.get('/assets/javascripts/jury/jury/' + $routeParams._id + '.json').
    success(function(data){                      
        callback(data)
    }).error(function(){
        /*handle errors however you want */
        callback(false);  
    })};
return factory;
}

I get this error Error: [ng:areq] Argument 'juryDetailCtrl' is not a function, got undefined

Anyhelp with juryDetailCtrl would be much appreciated

6 Answers 6

2

It will be better from structure wise, if you make $http.get call from service or factory then call it in any controller like:

angular.module('myApp')

.factory('myFactory', function ($http) {
    return {
        list: function() {
            return $http.get('/myURL/list').then(
                    function(result) {
                        return result.data;
                });
        }
    };
});

Then from controller:

.controller('myController', ['$scope', 'myFactory',
    function($scope, myFactory) {
        myFactory.list().then(
        function(data){
            $scope.myData = data;
        });
}]);

and from another controller:

.controller('myController2', ['$scope', 'myFactory2',
    function($scope, myFactory2) {
        myFactory2.list().then(
        function(data){
            $scope.myData = data;
        });
}]);

and so on..

Sign up to request clarification or add additional context in comments.

6 Comments

so if I want data from two factories would this work here as well?
yes, you can simply call any other factory like: .controller('myController2', ['$scope', 'myFactory2', function($scope, myFactory) { myFactory.list().then( function(data){ $scope.myDataFromMyFactory = data; }); anotherFactory.list().then( function(data){ $scope.myDataFromAnotherFactory = data; }); }]);
sorry @pixeltooth looks like no code formatting in comments here!
do factories need a new module created?
no, you just need to chain it to your main module like angular.module('myApp').factory(){}.controller(){} and so on.. no extra module for factory itself
|
2

To share data between two controllers you would use a service. A service is a singleton instance and if you store your table inside the controller it would be persistent.

See the Angular documentation for how to creater a service
Example can be found here (scroll down a bit): https://docs.angularjs.org/tutorial/step_11.

Comments

2

I would personally use a factory,

something like

    app.factory('listFactory', function($http){
        var factory = {};

        factory.getList = function(list, callback){
            $http.get('/assets/javascripts/plop/plop/'+list+'.json').
            success(function(data){                      
                callback(data)
            }).error(function(){
                /*handle errors however you want */
                callback(false);  
            })};

        return factory;

    }

then use it like so in your controller

    listFactory.getList($routeParams._id, function(list){
         if(list !== false){
              $scope.plopor = list;
         }
    })

or

    listFactory.getList('plopies', function(list){
         if(list !== false){
              $scope.plopor = list;
         }
    })

Comments

2

You should create a Service which would download your data. This Service should be injected to your controllers the same way you inject $scope etc.:

yourModule.service('yourService', ['$http', YourServiceFunction]);
yourModule.controller('plopDetailCtrl', ['$scope', '$routeParams', 'yourService', YourPlopDetailCtrlFunc])

You will be able to get data from service in any controller with this service injected.

Comments

1

Also, you might want to have a look at angular-ui-router which is an addon, replacing the original router. Have a look at the exemples, you'll see it does what you want, and more !

I've discovered it recently and wish I've used it before getting deep with the "normal" router.

Comments

1

Basically services/factories are consistent and are only loaded once when they are called. Controllers are not, when you changed your page, the controller is reinitialized so you can't store anything in it.

By putting you data into a service, you can then bind the value from your services/factories to your template through your controller. Controller that will only serve as a link, and will not perform anything else (maybe ask the service/factory to reload or stuff like that). You can also save some API call if you want, by only calling it when you don't already have the data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.