Search code examples
javascriptangularjshttpxmlhttprequestng-controller

How to implement multiple ng controllers with http calls in AngularJS?


In an app / on a page I have several places, where data should be loaded asynchronously. E.g.: a DIV with images and another one with cateories (for the navi). I implement it like this:

app.js

(function() {
    var app = angular.module('portfolio', []);
    app.controller('ProjectsListController', ['$http', function($http) {
        var projectsList = this;
        projectsList.projectsListData = [];
        $http.get(config['api_server_url'] + '/projects').success(function(data) {
            projectsList.projectsListData = data;
        });
    }]);
    app.controller('NaviCategoriesController', ['$http', function($http) {
        var categoriesList = this;
        categoriesList.categoriesListData = [];
        $http.get(config['api_server_url'] + '/categories').success(function(data) {
            categoriesList.categoriesListData = data;
        });
    }]);
})();

list.phtml

<!-- projects -->
<div id="projects" ng-app="portfolio">
    <div id="projectsList" ng-controller="ProjectsListController as projectsList">
        <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects">
            <div class="project-image">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>
</div>

navi-categories .phtml

<!-- navi-categories -->
<div id="navi-categories" ng-app="portfolio">
    <ul id="categoriesList" ng-controller="NaviCategoriesController as categoriesList">
        <li class="categoryItem" ng-repeat="categoryItem in categoriesList.categoriesListData._embedded.categories">
            <a href="/categories/{{categoryItem.tech_name}}" title="{{categoryItem.title}}">{{categoryItem.short_name}}</a>
        </li>
    </ul>
</div>

Every of these two blocks works fine. But I cannot use both at the same time. That means: The categories only get displayed, when the projects/images list is commented out (in the HTML) -- when I activate the list, the categories' HTTP request doesn't get sent anymore.

What am I doing wrong? How to implement this correctly?


Solution

  • Well... the problem is that they both have the ng-app="portfolio". You should wrap both components in one div with the ng-app="portfolio" attribute:

    <div id="app" ng-app="portfolio">
        <div id="projects">
            <div id="projectsList" ng-controller="ProjectsListController as projectsList">
                <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects">
                    <div class="project-image">
                        <img
                            ng-src="{{projectItem._embedded.images[0].src}}"
                            title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                            alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                        />
                    </div>
                </div>
            </div>
        </div>
    
        <div id="navi-categories">
            <ul id="categoriesList" ng-controller="NaviCategoriesController as categoriesList">
                <li class="categoryItem" ng-repeat="categoryItem in categoriesList.categoriesListData._embedded.categories">
                    <a href="/categories/{{categoryItem.tech_name}}" title="{{categoryItem.title}}">{{categoryItem.short_name}}</a>
                </li>
            </ul>
        </div>
    </div>