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.