1


for the passed few days I am struggling with the matter of AngularJS. I am novice at this and that's where my troubles result from.
Anyway here is my problem. I have an app that is made made for asking users some questions, collecting answers and displaying them to the user.
The HTML is:

   <div ng-repeat="dialog in dialogWindows">
                <div id="{{dialog.idName}}" class="bold abs">   
                    <div class="questionContainer rel">


         <a href=""><button ng-click="compute()>Fake results</button></a>

                        <div ng-repeat="input in dialog.inputs">
                        <input type="radio" id="{{input.radio}}" name="{{dialog.name}}" value="{{input.value}}">
                        <label for="{{input.radio}}" class="answer abs {{input.a}}">{{input.answer}}</label>


                        </div>
                        </div>



                </div>
                </div><!--/ng-repeat-->
             </div><!--/ng-controller-->

And here is the JS managing the ng-repeat above:

function dialogWindows($scope,localStorageService){

    $scope.dialogWindows = [
    {id:0, 
    idName:"pigmentation", 
    number:"1", 
    name:"Pigmentation",
    answer1:"Clear complexion",
    answer2:"Semi-swarthy complexion",
    answer3:"Swarthy complexion",
    answer4:"",
    answer5:"",
    answer6:"",

    href:"#hairColor",
    hrefBack:"index.html",
    inputs:[{id:0,a:"a1",answer:"Clear compexion", radio:"radio1",value:"1"},
            {id:1,a:"a3", answer:"Semi-swarthy complexion", radio: "radio2",value:"1"},
            {id:2,a:"a5",answer:"Swarthy complexion",radio:"radio3",value:"1"}

            ]

Nothing really complicated and so far it works fine. Now you can see that ng-repeat generates three radio buttons. and we have compute function assigned to the button soon you'll see what it does. Here is the compute() function:

$scope.compute = function() {



    if (document.getElementById('radio1').checked) {

        $scope.a.push(1);
        $scope.b.push(1);
        $scope.c.push(1);
        $scope.d.push(1);
        $scope.e.push(1);
        $scope.f.push(1);
        $scope.g.push(1);
        $scope.h.push(1);
        $scope.i.push(1);
        $scope.j.push(1);
        $scope.k.push(1);
        $scope.l.push(1);
        $scope.m.push(1);
        $scope.n.push(1);
        $scope.o.push(1);
        $scope.p.push(1);

    } else if (document.getElementById('radio2').checked) {

       $scope.r.push(1);
       $scope.s.push(1);
       $scope.t.push(1);
       $scope.u.push(1);
       $scope.w.push(1);


    } else if(document.getElementById("radio3").checked){
        $scope.z.push(1);
        $scope.x.push(1);
        $scope.y.push(1);
        $scope.q.push(1);
        $scope.ab.push(1);

        }

Answered questions are passed to one of 12th arrays responsible for collecting answers. JS:

$scope.a= [];
    $scope.b= [];
    $scope.c = [];
    $scope.c= [];
    $scope.d= [];
    $scope.e= [];
    $scope.f= [];
    $scope.g= [];
    $scope.h = [];
    $scope.i= [];
    $scope.j= [];
    $scope.k= [];
    $scope.l= [];
    $scope.m= [];
    $scope.n= [];
    $scope.o= [];
    $scope.p= [];
    $scope.r= [];
    $scope.s= [];
    $scope.t= [];
    $scope.u= [];
    $scope.w= [];
    $scope.z= [];
    $scope.x= [];
    $scope.y= [];
    $scope.q= [];
    $scope.ab= [];

Then I wrote a list of elements each one representic one array, that is...

<div ng-repeat="record in records">
<a href="{{record.link()}}"><div class="rel fptsans {{record.className()}}">{{record.item}}</div></a>
</div>

ng-repeat is generated with this records array as below:

$scope.records = [
    {id:0, 
    className :  $scope.a.length > 0 ? 'special' : 'normal',    
    item: "a",
    link: $scope.className == "special" ? "a.html" : ''

    },
    {id:1,
    className: $scope.b.length > 0 ? 'special' : 'normal',
    item:"b",
    link: $scope.className == "special" ? "b.html" : ''

    },
    {id:2,
    className:  $scope.c.length > 0 ? 'special' : 'normal',
    item:"c",
    link: $scope.className == "special" ? "c.html" : ''
    },
//and so on to 12th.

I was sure that every part of the app was consistent but soon I was about to get surprised that Angular doesnt show any results within the ng-repeat="record in records" because it is reffering to an empty objects ($scope.a = []; is in fact empty at initialization), despite that I am able to view the length of an array by simply writing in my html {{a.length}} so apparently the length of an array is increasing. My question is how may I use $scope.[some array].length inside my angular array. Should I use ng-model with radio buttons ? would it be helpful ? How can I solve this problem which currently made me stuck in one place.Please help I am really out of solutions. Thank You in advance

codeman
  • 47
  • 1
  • 3
  • 9

1 Answers1

0

I think you are populating the $scope.records before the compute is being called. That would result to empty array at the beginning. You need to re-populate the $scope.records by watching your arrays. Look up $watch and see how it works. I personally think you should not put all of those a, b, c, etc. items in the $scope but you should put them in some thing like $scope.Questions.a, $scope.Questions.b, $scope.Questions.c, etc. Then you can create a watch on $scope.Questions or individual items.

[Edit] I see where is the problem! Before I start to explain the situation I want to recommend you to read more about AngularJS and how to think in AngularJS world (maybe this can help "Thinking in AngularJS" if I have a jQuery background?)

There are a few problems with your code: First you didnt have {{ in your class definition

<div class="record.className}}">

i fixed it:

<div class="{{record.className}}">

the other problem was that you were initializing the ClassName and Link properties of $scope.records in the initialization of the controller and you never updated those values based on the changes in apenic. That means the $scope.Records is being initialized when $scope.alepnic is empty hence both records would have the class "normal". Now if you increase the length of $scope.Records nothing is updating your records to reflect the changes. I moved the initialization code into the compute method so your records are re-evaluated every time your array changes.

the updated code: http://jsfiddle.net/Tb9j5/8/

$scope.compute=function()
{
    $scope.alpeic.push(1);
    $scope.records = [
    {id:0,
     link:$scope.alpeic.length > 5 ? "alpeic.html" : "",
     className:$scope.alpeic.length > 5 ? "special" : "normal",
     item:"This is item A"},
    {id:1,
    link:$scope.alpeic.length > 5 ? "alpeic.html" : "",
    className:$scope.alpeic.length > 5 ? "special" : "normal",
     item:"This is item B"}];
}

$scope.compute();

This is not the best Angular method to solve your problem but is the easiest one to communicate to you. The other ways is to setup a $watch on your alpeic array and then re-evaluate the properties in your $scope.Records. Also you could and should use ng-class to set class atrributes without needing a scope:

<div ng-repeat="record in records">
    <a href="alpeic.html">
        <div ng-class="{special: alpeic.length >= 5, normal: alpeic.length < 5}">{{record.item}}</div>
   </a>                          
</div>
Community
  • 1
  • 1
Aidin
  • 2,134
  • 22
  • 26
  • Thank you for the answer. I tried using $watch on $scope.a = []; like this: $scope.$watch('a', compute, true); but the console returned the error $watch undefined. – codeman Oct 26 '13 at 19:06
  • where are you getting the $scope from? is it dependency injected by angular? – Aidin Oct 26 '13 at 21:18
  • I am not sure I understand you well. I mean the $scope.$watch is placed inside dialogWindows controller. I use standard syntax for $watch as it is described for example in "AngularJS" by Brad Green and Shyam Seshadri. – codeman Oct 27 '13 at 12:00
  • I think I will prepare a short Fiddle to illustrate most neuralgic issues. – codeman Oct 27 '13 at 17:30
  • As I said in the previous post here is the fiddle which presents the issue - http://jsfiddle.net/adeling/Tb9j5/ – codeman Oct 29 '13 at 18:59
  • Aidin i have one more request to You - could you please write it also with the $watch method ? – codeman Oct 30 '13 at 17:00
  • Sorry for late response. This is the version that uses watch: http://jsfiddle.net/2LX69/ – Aidin Nov 03 '13 at 18:54
  • Hello Aidin, thank you very much but I guess something is wrong with the fiddle because the version that I open is your previous one :) – codeman Nov 03 '13 at 22:08