Jordan
Jordan

Reputation: 231

AngularJS - Populating HTML Drop-Down with JSON from REST API (without $scope)

A lot of solutions on Stack Overflow in relation to populating drop down menus include $scope.

My second drop-down depends on the value of my first drop-down therefore I use ng-changeon the first HTML select to parameter pass the model ID into the 2nd drop-down's function.

1st Drop-Down HTML and Angular JS:

<select data-ng-controller="addAssetController as addAssetCtrl" id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">

    <option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
        {{functionalOrg.id}} - {{functionalOrg.account}}
    </option>

</select>

Hence ng-change:

ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)"

-

var vm = this;

functionalOrganisationRepository.getFunctionalOrganisation().then(function (results) {
    vm.functionalOrgs = results;
}, function (error) {
    vm.error = true;
    vm.errorMessage = error;
});

The 2nd Drop-Down HTML and Angular:

<select data-ng-controller="addAssetController as addAssetCtrl" id="location" data-ng-model="addAssetFormCtrl.location.id">

    <option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
        {{location.id}} - {{location.address6}}
    </option>

</select>

-

vm.getLocations = function(id) {

    console.log("Functional org ID:" + id);

        locationRepository.getLocation(id).then(function (results) {
            vm.locations = results;
        }, function (error) {
            vm.error = true;
            vm.errorMessage = error;
        });
}

Assuming my service layer is fine and brings back a JSON object with everything I require, what could the problem be? The vm.getLocations function is definitely getting called because my console log is being printed. The service layer is also fine because a JSON object to being logged to my command prompt.

My question is how do I populate my second drop-down from whatever JSON is returned by getLocations? Please hence I do not want to make use of $scope in Angular.

Upvotes: 0

Views: 1205

Answers (3)

manzapanza
manzapanza

Reputation: 6235

The "ng-controller" attribute is repeated on each select. Put the attribute only one time on a parent element!

<div data-ng-controller="addAssetController as addAssetCtrl">

<!-- Drop Down 1 and 2 here -->

</div>

Upvotes: 1

ipsi
ipsi

Reputation: 2070

Pretty sure that this is because they have different scopes and different controllers.

Assuming that the actual HTML looks like the following:

<select data-ng-controller="addAssetController as addAssetCtrl" id="location" data-ng-model="addAssetFormCtrl.location.id">

    <option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
        {{location.id}} - {{location.address6}}
    </option>

</select>

<select data-ng-controller="addAssetController as addAssetCtrl" id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">

    <option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
        {{functionalOrg.id}} - {{functionalOrg.account}}
    </option>

</select>

Then, to the best of my knowledge, each select will get a different instance of the controller, each with different scopes. So you've effectively got a controller addAssetCtrl1 and addAssetCtrl2, so setting data on 1 does not set it on 2.

The solution would be to set the data on a parent controller, or, probably more simply, to do the following:

<div data-ng-controller="addAssetController as addAssetCtrl">
    <select id="location" data-ng-model="addAssetFormCtrl.location.id">

        <option data-ng-repeat="location in addAssetCtrl.locations | orderBy:'id' track by $index" value="{{location.id}}">
            {{location.id}} - {{location.address6}}
        </option>

    </select>

    <select id="functionalOrg" data-ng-model="addAssetFormCtrl.functionalOrg.id" ng-change="addAssetCtrl.getLocations(addAssetFormCtrl.functionalOrg.id)">

        <option data-ng-repeat="functionalOrg in addAssetCtrl.functionalOrgs | orderBy:'id' track by $index" value="{{functionalOrg.id}}">
            {{functionalOrg.id}} - {{functionalOrg.account}}
        </option>

    </select>
</div>

Upvotes: 0

Nix
Nix

Reputation: 58572

If you dont share scope you can't do what you want to do. Meaning if you dont have a parent vm or pass something to your directive = you can't tell what is selected.

Pull up your controller a level and share it among selected or you are going to have to either watch a shared variable in a service, or rely on $on & $broadcast to communicate.

Upvotes: 0

Related Questions