简体   繁体   中英

Using angular.forEach with JSON

What I'm trying to do with my app and controller is make a "flow chart style" question and answer system. How I'm keeping track of the Current question and answer to show is using $scope.ActiveQuestion and an array called $scope.ActiveAnswers .

I'm having trouble understanding Angularjs foreach method. I'm used to using for loops in javascript and I'v tried looking for something that can explain foreach compared to a basic for loop, I'v found nothing. But here is basically what I'm trying to do with the foreach.

For each answerIDs in the current $scope.questions[$scope.ActiveQuestions].answerIDs , I want to go into Answers and pull that Array that contains that idAnswer and push it into a newly create empty array called $scope.ActiveAnswers . This will let me use ng-repeat in a template with the answers required for that question.

You can see my Json data and my current Controller code below:

app.controller('QuestionsCtrl', function($scope, $http) {

    // Pull Questions data
    $http.get("includes/getQuestions.php")
    .success(function(response) {
        $scope.Questions = response;
        $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    });
    // Pull Answers data
    $http.get("includes/getAnswers.php")
        .success(function(response) {
            $scope.Answers = response;
        });

    // Assign First Question
    if ($scope.ActiveQuestion == null) {
        $scope.ActiveQuestion = 1;
    };
    $scope.ActiveAnswers = [];
    angular.forEach($scope.Answers, function(idAnswers) {
        angular.forEach($scope.ValidAnswers, function(value) {
            if(value==idAnswers) {
                this.push(Answers)
            };
        });
    },$scope.ActiveAnswers);

});

Questions:

[
    [], {
        "idQuestion": "1",
        "answerIDs": "1",
        "text": "Don't know what to watch?"
    }, {
        "idQuestion": "2",
        "answerIDs": "2,3,4",
        "text": "Okay! First question: How new to anime are you?"
    }, {
        "idQuestion": "3",
        "answerIDs": "5,6,7,8,9,10",
        "text": "So your new! Awesome I've got a ton of anime for you, But lets get more specific. What type of anime interests you?"
    }, {
        "idQuestion": "4",
        "answerIDs": "11,12,13",
        "text": "Cool, Cool. What setting would you like?"
    }
]

I'v created an array of answers:

[
    [], {
        "idAnswer": "1",
        "nextQuestion": "2",
        "text": "Click here to get started",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "2",
        "nextQuestion": "3",
        "text": "...I've seen some GIFs",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "5",
        "nextQuestion": "4",
        "text": "Fantasy Action Adventure",
        "animeID": null,
        "checkType": "0"
    }, {
        "idAnswer": "11",
        "nextQuestion": null,
        "text": "Steampunk (magic, guns, early 1900s)",
        "animeID": "1",
        "checkType": "1"
    }
]

Weird thing is I'm not getting any errors but it's not filling the ActiveAnswers array either. Any help would be greatly appreciated.

UPDATE

It should be mentioned that I'm storing my data originally in a MySQL data base and fetching the data with PHP encoding it into Json.

You can use promise and $q.defer() promise manager to handle your request.

By definition, $http return promise.

$q.defer() get 2 methods :

  • resolve(value) : which resolve our associated promise, by giving her the final value

  • reject(reason) : which resolve an promise error.

Controller

(function(){

function Controller($scope, Service, $q) {


  var defer = $q.defer();

  //create promise
  var promise1 = Service.get('includes/getQuestions.php"');

  var promise2 = Service.get('includes/getAnswers.php');

  //Create promise with $q
  var promiseAnswer = defer.promise;

  if ($scope.ActiveQuestion == null) {
      $scope.ActiveQuestion = 1;
  };

  //Retrieve data from promise1 & promise2
  $q.all([promise1, promise2]).then(function(response){
    //Get our question data
    $scope.Questions = response[0].data;
    //Get our answer data
    $scope.Answers = response[1].data;
    $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    $scope.ActiveAnswers = [];

    $scope.Answers.forEach(function(elm){
      $scope.ValidAnswers.forEach(function(value){
        //Access to elm.idAnswer and not just elm
        if (value === elm.idAnswer){
          $scope.ActiveAnswers.push(value);
        }
      });
    });

    //Resolve our data
    defer.resolve($scope.ActiveAnswers);

  });

  //When all the data are processed, retrieve our data
  promiseAnswer.then(function(data){
    console.log(data);
  });

}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

Then, you should uses a Service for the request processing :

Service

(function(){

  function Service($http){

    function get(url){
      //Return a promise with specific url
      return $http.get(url);
    }

    var factory = {
      get: get
    };

    return factory;

  }

  angular
    .module('app')
    .factory('Service', Service);

})();

As you get multiple asynchonous requests, it's a good practice to use promise and $q.defer() .

I advise you to make an arrangement in question, called, say "Answer", keep it in an array and recorras, something like:

[
 ["Question"],
   ["Answer"]
   {
    "idAnswer": "1",
    "nextQuestion": "2",
    "text": "Click here to get started",
    "animeID": null,
    "checkType": "0"
   },
]

Should not fail your loop

With all of your help. I figure out how to avoid modifying my database and finally got the foreach loops to work. although it's still broken, never the less the issues I am facing in this question has been resolved. Here is my updated code.

app.controller('QuestionsCtrl', function($scope, $http, $window) {

// Assign first question
if ($scope.ActiveQuestion == null) {
    $scope.ActiveQuestion = 1;
};
// Pull questions data
$http.get("includes/getQuestions.php").success(function(responseQuestions) {
    $scope.Questions = responseQuestions;
    $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");

    // Pull answers data
    $http.get("includes/getAnswers.php").success(function(responseAnswers) {
        $scope.Answers = responseAnswers;
        $scope.getActiveAnswers();
    });
});

$scope.getActiveAnswers = function() {
    $scope.ValidAnswers = $scope.Questions[$scope.ActiveQuestion].answerIDs.split(",");
    $scope.ActiveAnswers = [];
    angular.forEach($scope.ValidAnswers, function(answerid) {
        angular.forEach($scope.Answers, function(answer) {
            if (answer.idAnswer == answerid) {
                $scope.ActiveAnswers.push(answer);
            };
        });

    }, $scope.ActiveAnswers);
}

$scope.answerclick = function(nextQuestion) {
    $scope.ActiveQuestion = nextQuestion;
    $scope.getActiveAnswers();
};

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM