1

I have figured out how to populate the first dropdown menu from the database with Angular, but I am stuck on how to grab the selected value of the first dropdown box to query to populate the second box. Also, if the data is in separate tables, will I have to make an API call everytime a dropdown is selected? I have seen plenty of examples doing this with pre set tables, but not with actual api calls. This is where I get confused.

Here is what I have now.

app.controller('SelectOptGroupController', function($scope,$http) {
        $http.get('api2.php').
        success(function(data) {
            $scope.animals = data;
        });
         $scope.species= [];
         $scope.getOptions2 = function(){
            //NOT SURE FROM HERE
          };

  })

HTML file

<div ng-controller="SelectOptGroupController" class="md-padding selectdemoOptionGroups">
          <div>
            <h1 class="md-title">Select Animal</h1>
            <div layout="row">
              <md-select ng-model="animals" placeholder="Animals" ng-change="getOptions2()">
                <md-option ng-repeat="animal in animals" value="{{animal.animal}}">{{animal.animal}}</md-option>
              </md-select>
              <md-select ng-model="species" placeholder="Species">
                <md-option ng-repeat="spec in species" value="{{spec.animal_species}}">{{spec.animal_species}}</md-option>
              </md-select>

          </div>
        </div>

As of now the database has one table with two columns being animal and animal_species. There are multiple species of the same animal, for example there are three inserts with the animal name of bear but each of the animal_species are different grizzly, black, and polar. Thanks for any help!

1 Answer 1

2

For your first question the ng-model of the md-select will correspond to the selected animal in the collection, so in this example $scope.model.selectedAnimal, would be the variable you can use to access the selected animal.

<div ng-controller="SelectOptGroupController" class="md-padding selectdemoOptionGroups">
    <div>
        <h1 class="md-title">Select Animal</h1>
        <div layout="row">
            <md-select ng-model="model.selectedAnimal" placeholder="Animals" ng-change="getSpecies()">
                <md-option ng-repeat="animal in model.animals" value="{{ animal }}">{{ animal }}</md-option>
            </md-select>
            <md-select ng-model="model.selectedSpecies" placeholder="Species">
                <md-option ng-repeat="species in model.species" value="{{ species.animal_species }}">{{ species.animal_species }}</md-option>
            </md-select>
        </div>
    </div>
</div>

As for your repeated api calls question, you can either have the database return all species and manage the 'active' ones in the js, or use a service to cache each request so that at least each animal will only query the api once. This also keeps the data logic out of the controller to make it reusable (as well as easy to share data between multiple controllers/directives/services).

app.controller('SelectOptGroupController', ['$scope', 'animalService', function($scope, animalService) {
    $scope.model = {
        animals: [],
        species: [],
        selectedAnimal: '',
        selectedSpecies: {}
    };

    animalService.getAnimals().then(function(data){
        $scope.model.animals = data;
    });

    $scope.getSpecies = function(){
        animalService.getSpecies($scope.model.selectedAnimal).then(function(data){
            $scope.model.species = data;
        }); 
    };
}]); //TYPO WAS HERE

app.factory('animalService', ['$http', '$q', function($http, $q){
    var cache = {};

    return {
        getAnimals: function(){
            return $http.get('api2.php').then(function(result) {
                return result.data;
            });
        },
        getSpecies: function(animal){
            if(cache[animal]){
                return $q.when(cache[animal]);
            } else{
                return $http({
                    url: 'whatever.php',
                    method: 'GET',
                    params: {
                        animal: animal
                    }
                }).then(function(result){
                    cache[animal] = result.data;
                    return cache[animal];
                });
            }
        }
    };
}]);

If you want to get all species in one go and just filter on the front end you can do something like this:

app.controller('SelectOptGroupController', ['$scope', 'animalService', function($scope, animalService) {
    $scope.model = {
        animals: [],
        species: [], //this will contain selected animals species
        allSpecies: [], //this will contain all species for all animals
        selectedAnimal: '',
        selectedSpecies: {}
    };

    animalService.getAnimals().then(function(data){
        $scope.model.animals = data;
    });

    animalService.getSpecies().then(function(data){
        $scope.model.allSpecies = data;
    });

    $scope.getSpecies = function(){
        //this filters out the species for the selected animal
        $scope.model.species = $scope.model.allSpecies.filter(function(species){
            return species.animal === $scope.model.selectedAnimal;
        });
    };
}]);

app.factory('animalService', ['$http', '$q', function($http, $q){
    return {
        getAnimals: function(){
            return $http.get('api2.php').then(function(result) {
                return result.data;
            });
        },
        getSpecies: function(animal){
            return $http.get('api3.php').then(function(result){
                return result.data;
            });
        }
    };
}]);
Sign up to request clarification or add additional context in comments.

7 Comments

Is there a dependency that I need to add to angular.module for this? I am getting the $injector error when trying to run this. Thanks
No, these are all default angular services except animalService, which is created here. I did notice a typo at the end of the controller, I forgot to add the closing square bracket ( ] ). I updated the code and added a comment to point out where my mistake was. If that doesn't work let me know what service the injector says it is having trouble finding
Your api3.php is returning every species every time. My original code assumed each api call would return the specific animals species (like deer). I added a second set of code for if you want to continue returning everything at once
In api3.php is there a way to get the animal selected to put into the SELECT sql statement?
Yea you would use a where statement: w3schools.com/sql/sql_where.asp, something like SELECT * FROM species WHERE animal = 'deer' (except with a php variable that is passed in from angular). I don't really know php, so I can't help with that part!
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.