Cannot Access Fields after adding Array to another Array - javascript

I have an array of sections where a section is pushed into the array when the user clicks a checkbox. It is defined like this:
$scope.print = {
sections:[]
};
Once I have all of the selected Sections, I use a service to get a list of questions for each selected section like this:
var questions = [];
myService.getQuestions(id)
.success(function (data) {
questions = data;
});
Then I assign the returned questions to the original array like this:
angular.forEach($scope.print.sections,
function (value, key) {
if (value.QuestionSectionID === id) {
$scope.print.sections[key].questions = questions;
}
});
The assignment "seems" to work, but I am unable to access the particular fields in the questions array by their field names.
On my HTML page, I have this:
<div ng-repeat="ps in print.sections">
<div>
<h4>{{ps.vchSectionName}}</h4>
</div>
<div ng-repeat="section in ps.questions">
<div ng-repeat="q in section">
{{q.vchQuestionText}}
</div>
</div>
</div>
When I try to access the "q.vchQuestionText" field, my HTML is blank, however if I simple do the following:
<div ng-repeat="q in section">
{{q}}
</div>
I can then see ALL of the information contained in each field of "q". But I need to access each field in "q" by it's name. What am I missing here?
Any assistance is greatly appreciated!

Okay, the reason I could display all the data in "q", but could not specify a field is because I had one too many ng-repeat directives.
All I needed was the following:
<div ng-repeat="ps in print.sections">
<div>
<h4>{{ps.vchSectionName}}</h4>
</div>
<div ng-repeat="q in ps.questions">
{{q.vchQuestionText}}
</div>
</div>
Hopefully, this will help someone else. Thank you all for your help.

Related

How to use localStorage value filter in ng-repeat

I've set a value when the user click vote choice. Its working.
.then(function(response) {
localStorage.setItem('isClicked', 'Yes');
var i = +localStorage.key("nid");
var nidId = 'nid' + localStorage.length;
localStorage.setItem(nidId, vm.nid);
vm.clickedBefore = true;
})
This is my HTML scope:
<div class="card myfunc" ng-repeat="myfunc in myfuncPage.myfuncs" id="{{myfunc.nid}}" >
<div class="item item-text-wrap">
<h2 class="item-icon-left"><i class="icon ion-ios-analytics"></i>
{{myfunc.title}}</h2>
</div>
<div class="item item-text-wrap" ng-show="localstorage">
<img ng-src="{{myfunc.field_image.und[0].imgPath}}"/>
<p class="custom-class" ng-bind-html='myfunc.body.und[0].value'>
</p>
<ul ng-repeat="vote in myfunc.advmyfunc_choice">
<li ng-repeat="voteselect in vote">
<div class="row">
<button class="col button button-outline button-dark" ng-click="myfuncPage.sendNid(myfunc);myfuncPage.sendVote(voteselect);showVoted = ! showVoted" >{{voteselect.choice}}</button>
<div class="voted-screen" ng-show="showVoted">
<h3>Thanks.</h3>
</div>
</div>
</li>
</ul>
</div>
</div>
In basically, I need remember the div via localStorage and when the page refresh, hide choice divs.
ng-show="showVoted" working on click but I need on refresh.
What is the best way to do it? Thanks.
I am not sure what local storage module you are using, so I can't be specific, but I would write factory that handles the retrieval and storage of the values you need
(function () {
var voteFactory = function (localStorage) {
return {
getVote: function (key) {
var isVoted = false;
// get local storage item, set voted etc
var voted = localStorage.getItem(key);
if(voted) {
isVoted = voted;
}
return isVoted;
},
setVote: function(key, value) {
localStorage.setItem(key,value);
}
};
};
app.factory('voteFactory', ['localStorage', voteFactory]);
})();
Then within the scope controller/directive you are using to show or hide you would have a function:
$scope.showVoted = function(key) {
return voteFactory.getVote(key);
}
then ng-show="showVoted(theidentifieryouwantouse)"
It is also worthwhile to mention I would use ng-if instead of ng-show. To be more efficient you could store your votes as an array instead of individual values and do a check to see if you have retrieved all values, get from local storage if not. Then your functions would interrogate retrieved array instead of repeated calls to local storage. I would also advice maybe using a promise in the factory because retrieval from local storage could be delayed causing some ui oddities.
Hopefully this is along the lines of what you are looking for. I can elaborate if needed.

Event in Angular Controller Only Fires Once

I'm trying to implement an Angular version of an autocomplete textbox. I found some working examples, but none seem to exhibit the behavior I'm getting.
The autocomplete functionality itself works fine. When a suggested item is selected, the control correctly handles the selection. Subsequent uses of the control (typing in the autocomplete box, making a selection) fail to engage the 'selected' event/condition, although the autocomplete bit continues to work.
Here's my module & controller:
var app = angular.module('myapp', ['angucomplete-alt']); //add angucomplete-alt dependency in app
app.controller('AutoCompleteController', ['$scope', '$http', function ($scope, $http) {
//reset users
$scope.Users = [];
$scope.SelectedUser = null;
//get data from the database
$http({
method: 'GET',
url: '/UserRoleAdministration/Autocomplete'
}).then(function (data) {
$scope.Users = data.data;
}, function () {
alert('Error');
})
//to fire when selection made
$scope.SelectedUser = function (selected) {
if (selected) {
$scope.SelectedUser = selected.originalObject;
}
}
}]);
I'm guessing the problem is in there, but I don't know what it is. I include the bit from my view below, although there doesn't seem to be much there to fuss with:
<div class="form-group">
<div ng-app="myapp" ng-controller="AutoCompleteController">
<div angucomplete-alt id="txtAutocomplete" pause="0" selected-object="SelectedUser" local-data="Users" search-fields="RegularName" placeholder="People Search" title-field="RegularName" minlength="2" input-class="form-control" match-class="highlight"></div>
<!--display selected user-->
<br /><br />
<div class="panel panel-default" id="panelResults">
<div class="panel-heading"><h3 class="panel-title">Manage Roles for {{SelectedUser.RegularName}}</h3></div>
<div class="panel-body">
<div class="row">
<div class="col-md-2">
<img src="~/Images/avatar_blank.png" width="100%" />
</div>
<div class="col-md-4">
<div class="row">
<div class="col-md-4">Selected User:</div> <div class="col-md-6">{{SelectedUser.RegularName}}</div>
</div>
</div>
</div>
</div>
</div>
</div>
Any help would be appreciated!
UPDATE
After fixing the mistake Yaser pointed out, I wasn't getting any information regarding the selected object. So I set the page to output the entire object, rather than the specified fields, and I noticed I was getting information about the selected object, and on subsequent attempts as well.
So this worked: {{SelectedUser}}
This did not: {{SelectedUser.Department}}
Then I looked at the object and noticed its format. It had "title" and "description", and description had inside it the key/value pairs.
So now this works: {{SelectedUser.description.Department}}
And that's it.
Because the first time you are setting $scope.SelectedUser as a function but inside that you are rewriting the same one with an object. so next time it is not a function any more, try to rename the function:
$scope.setUser = function (selected) {
if (selected) {
$scope.SelectedUser = selected.originalObject;
}
}

Sorting out array of parent child relations where two children share a parent from an array and display it using div

I have the following data which gets served from a neo4j query, The data that gets sent back is in the format
home->parent->child1
home->parent->child2
home->parent2->child1
home->parent3->child1
home->parent3->child2
home->parent3->child3
I am trying to use javascript to display html which should be like this
<div id="parent1">
<div id="child1"></div>
<div id="child2"></div>
</div>
<div id="parent2">
<div id="child1"></div>
</div>
i tried loopong throigh the query and trying to get the parent to be the index of an object and the child to be values under it
i would do this like this in php
$jsonContents = (object)("parent"=>"child","parent"=>"child"....);
$array = array();
foreach($jsonContents as $jsCo=>$jsoCont){
$array[$jsoCont->parent][] = $jsoCont->child;
}
this would return the
$array as
home->parent1->[0]->child
->[1]->child
parent2->[0]->child...
This would let me avoid the check for uniqueness of the home parent category as well as put them in a hierarchy so i can interpret it properly in my View part of MVC, to create my div structure.
this is the url for the example json data
http://www.jsoneditoronline.org/?id=bdda268982eb431d361c25e9035bbc99
No answers to this, solved it by myself.
Here
var data = 'data shown in link above';
var myArr = [];
$.each(data, function(index, element) {
var parent = String(element.parent.properties.name);
var child = String(element.child.properties.name);
if(myArr[parent]){
myArr[parent][(myArr[parent].length)] = child;
} else {
myArr[parent] = Array(child);
}
});
Hope this helps people. :)

Get $id from nested ng-repeat

I have a post/comment system in Angularjs and Firebase, I can loop without problem to show all the post with ng-repeat and its comments as well. The problem start when I tried to get the $id from the second nested ng-repeat to be able to save the replies into the comment. Let's see the code I have:
<div class="posts" ng-repeat="post in posts">
<div>{{post.text}}</div>
<div>
<input type="text" placeholder="Comment here..." ng-model="comment">
<button ng-click="addComment(post, comment)"></button>
</div>
<div class="comments" ng-repeat="cmt in post.comments">
<p>{{cmt.text}}</p>
<div>
<input type="text" ng-model="answer">
<button ng-click="addAnswer(cmt, post)"></button>
</div>
<div ng-repeat="answer in cmt.answers">
<p>{{answer.text}}</p>
</div>
</div>
</div>
app.js
$scope.addComment = function(post, comment){
var ref = new Firebase("https://url.firebaseio.com/users/" + post.$id + "/comments");
var comments = $firebaseArray(ref);
comments.$add({
text: comment
});
}
$scope.addAnswer = function(cmt, post){
var refanswers = new Firebase("https://url.firebaseio.com/users/" + post.$id + "/comments/" + cmt.$id + "/answers");
var answers = $firebaseArray(refanswers);
answers.$add({
text: answer
});
}
To test, first I remove the code above inside addAnswer function and write two console.log to check if Im getting the values
console.log(post.$id);
console.log(cmt.$id);
I get only the post.$id but no the second one (undefined), am I missing something about nested ng-repeat?
Edited: I changed the code to avoid the $scope conflict following the answers below but still does not work.
Any advice is welcome, thanks :)
comment being passed into addAnswer() is likely not the instance object of the ng-repeat as you are thinking, rather it could be clashing with the ng-model='comment' already defined above. You have a scope issue.
This may be fixed by changing ng-repeat="comment in post.comments" to ng-repeat="cmnt in post.comments"or whatever you want to name it, as long as it doesn't conflict with previously defined $scope objects.

iterate over all classes within a given class

<div class="contain_questions">
<div class="question">
<div class="question_text">First question</div>
<div class="question_mandatory">1</div>
<div class="options">
<div class="option"><div class="option_name">a</div><div class="option_value">1</div></div>
<div class="option"><div class="option_name">b</div><div class="option_value">2</div></div>
<div class="option"><div class="option_name">c</div><div class="option_value">3</div></div>
</div>
add_another_option
</div>
.
. // many more div.question ...
.
<input type="button" value="submit_questions" />
</div>
How do you use .each() for each div.option within an outer .each() for each question?
I have the outer .each() working fine, which iterates over all div.question and pushes the question_text etc into an array, however I cant seem to target the options container within each question in order to also push all of the options for each question into the array.
Also, is it possible to target a subset of the DOM with the .each() function, or is there some other way to iterate over all classes within a given class?
Thanks guys..
Just as simple as that:
$(".question").each(function() {
...
$(this).find(".option").each(function() {
...
});
});
So your code might look like the following:
var questions = [];
$(".question").each(function() {
var obj = {
name : $(this).find(".question_text").text(),
options : []
};
$(this).find(".option").each(function() {
obj.options.push({
name : $(this).find(".option_name").text(),
value : $(this).find(".option_value").text()
});
});
questions.push(obj);
});
console.log(questions);

Categories

Resources