3

I have an ng-include html element, and want to pass some data from outside to the controller.

The main controller fetches json data from a http webservice, and extracts the data into the scoped variable climadata.

The following is pseudocode, but you get the idea:

function mainController($scope, $http) {
    $http.get().then(
        $scope.climadata = response.clima;
    );
}

<div ng-controller="mainController">
    <div ng-include="'clima.html'" ng-controller="climaController" onload="climamodel = climadata"></div>
</div>

This works fine, BUT the climadata never reaches the climaController. Checked as follows:

function climateController($scope) {
    console.log($scope.climamodel); //prints "undefinied"
};

The climamodel is always undefined in console, but why?

7
  • 1
    You can use service to share the data.. Commented Oct 23, 2015 at 9:51
  • Isn't is possible without introducing a service for just handing the modeldata back and forth? Commented Oct 23, 2015 at 9:52
  • 1
    normaly, you don't to do anything to get climamodel from the mainController because it's the controller parent of climateController. Commented Oct 23, 2015 at 9:55
  • angular version? this should work Commented Oct 23, 2015 at 9:58
  • Possible duplicate of AngularJS : How can I pass variables between controllers? Commented Oct 23, 2015 at 10:00

5 Answers 5

6

This is working, the reason you getting the undefined is because, you get the data by $http request, because of that, before you get the data climaController will execute, at that point there is no scope variable call climadata.

check this DEMO

you can see the console is printing undefined but you will get the data on partial HTML page after the data is available after ajax request.

If you want to load the inclcude after the ajax is complete then use ng-if

<div ng-if="climadata" ng-include="'clima.html'" ng-controller="climaController"></div>

if climadata is present then only this div process that means include works only if climadata is available.

DEMO

and you can void from onload="climamodel = climadata"

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

1 Comment

I think this is main of the reason +1. But i did't test it.
0

Try this:

    function mainController($scope, $http) {
     $scope.data={};
        $http.get().then(
            $scope.data.climadata = response.clima;
        );
    }

    <div ng-controller="mainController">
        <div ng-include="clima.html" ng-controller="climaController">/div>
    </div>

2 Comments

I'm still getting undefined for console.log($scope.data.climadata) in climaController.
you have to do the console.log when you the $http.get deliver it's response.
0

I think the best way would be to use $broadcast

It is essentially a service to propogate events to child scopes(read: child controllers). The child controllers listen for the $broadcast event using the $on service.

Here's how you can implement it. In your MainController:

function mainController($scope, $http, $broadcast) { //injected broadcast
    $http.get().then(
        $scope.climadata = response.clima;
        $scope.$broadcast('climaData', $scope.climadata); //broadcast event 'climaData' and send '$scope.climadata' as argument.
    );
}

In your climateController:

function climateController($scope) {
    $scope.$on('climaData', function(event, args) { //listener for 'climaData' event.
        console.log(args); //args contains $scope.climadata sent from the main controller.
    }) 
};

Comments

0
  • First you need to change onload to ng-load or ng-init. because onload can't read the angular properties.

  • You can use $rootScope , It is helps to pass values from a controller to another controller.

function climateController($rootScope ) { console.log($rootScope.climamodel); };

Also some other details, you can get here : AngularJS: How can I pass variables between controllers?

5 Comments

This also gives me undefined.
@membersound, have you assigned climamodel to rootscope ?
No, just to normale $scope.
I would use a service.
@Cranio, How about directive ?
0

i think sharing data through scope inheritance creates spaghetti code. One should inspect your code and template to understand what is going on.

For your problem i would create a service which will load and cache data. This service could be injected to both controllers.

here is sample code

module.factory('UserService', ['$http', '$q', function($http, $q){
var userAPI = {};
var userData = null;
var isLoading = false;

userAPI.getMyData = function(){
    var deferred = $q.defer();
    if(userData != null){
        deferred.resolve(userData);
    } else if(isLoading === false) {
        isLoading = true;
        $http.get('/api/data/data').then(function(resp){
            userData = resp.data;
            deferred.resolve(userData);
        }, function(err){
            deferred.reject(err);
        });
    }

    return deferred.promise;

};

return userAPI;
}]);

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.