Each loop in html not working - pls help!


#1

Hi
I have a list of objects created in the server.js using the following piece of code…

var camList = [];
var parsedCamList = JSON.parse(camListForUser.content);
for (i = 0; i < parsedCamList.length; i++) {

            var domain = parsedCamList[i].IP.trim();
            var port = parsedCamList[i].Port.trim();
            var username = parsedCamList[i].Username.trim();
            var password = parsedCamList[i].Password.trim();
            //camListULRs = camListULRs+ '|'+ domain+':'+port+','+username+','+password;
            camList.push({
                "domainport": domain+':'+port,
                "camusername": username,
                "campassword": password
            });
        }

return camList;

How will I access this list in my client HTML(video.html)? I have tried using the each loop like the below but no luck

{{#each urlList}}

{{domainport}}

{{/each}}

the urlList was created using the below code.
code from video.js in Client

Meteor.call(‘cctvdetails’, tokenId, function (error, result) {
urlList = result;
});

Template.video.helpers({
urlList: function(){
console.log('frm geturllist: ’ + urlList[0])
return urlList;
}

});

Thanks


#2

My guess is that your urlList hasn’t been loaded yet when you try to display it. Is it stored in a reactive source? You should use a ReactiveVar, for example, so that the DOM is automatically updated once the list is loaded.


#3

I am not sure what the problem is hence struggling to figure out a solution. Is there any way i can find out what is going wrong? I dont see the urlList helper funtion being call from the html.


#4

It should (if you display the video template somewhere). Please post your html.


#5
<section id="logo-section" class="text-center">
    <div class="container">
        <div class="row">
            <div class="col-md-12">
                <div class="logo text-center">
                    <h4 style="color: rgb(218, 224, 232); margin:15px" class="harabarahand">Rakshak</h4>
                </div>
            </div>
        </div>
    </div>
    <nav class="navbar navbar-fixed-left navbar-minimal animate" role="navigation">
        <div class="navbar-toggler animate" style="background-color: #7fff96; margin-top: 5px">
            <span class="menu-icon"></span>
        </div>
        <ul class="navbar-menu animate">
            <li>
                <a href="#snapshot" class="animate" id="singleCam">
                    <span class="desc animate"> Single Camera</span>
                    <span class="glyphicon glyphicon-stop"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="fourCam">
                    <span class="desc animate"> Four Cameras </span>
                    <span class="glyphicon glyphicon-th-large"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="nineCam">
                    <span class="desc animate"> Nine Cameras </span>
                    <span class="glyphicon glyphicon-th"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="singleUser">
                    <span class="desc animate"> Single User</span>
                    <span class="glyphicon glyphicon-user"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="multiUser">
                    <span class="desc animate"> Multi User</span>
                    <span class="glyphicon glyphicon-user"></span>
                </a>
            </li>
            <li>
                <a href="#settings" class="animate" id="settings">
                    <span class="desc animate"> Settings Page </span>
                    <span class="glyphicon glyphicon-cog"></span>
                </a>
            </li>
            <li>
                <a href="#signout" class="animate" id="signout">
                    <span class="desc animate"> Sign Out </span>
                    <span class="glyphicon glyphicon-log-out"></span>
                </a>
            </li>
        </ul>
    </nav>
</section>

<div class="container" style="background-color: #c5c6c7; width: 90%; height : 90%">
    <ul>
        {{#each urlList}}
            <li>
                <img src="http://{{domainport}}/videostream.cgi?user={{camusername}}&amp;pwd={{campassword}}&amp;resolution=32&amp;rate=0" style="width: 49.5%; height: 49.5%; float: left"/>
                <div>
                    <a  id="left" target="main" style="float: left; margin-top: 10px"><img class="img-responsive" src="left.png" width="30" height="2" border="0" alt="" style="display:block;" /></a>
                    <a  id="leftstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="leftst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

                    <a  id="right" target="main" style="float: left;margin-left: 5px;; margin-top: 10px"><img class="img-responsive" src="right.png" width="30" height="22" border="0" alt="" style="display:block;" /></a>
                    <a  id="rightstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="rightst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

                    <a  id="top" target="main" style="float: left;margin-left: 5px; margin-top: 5px"><img class="img-responsive" src="top.png" width="22" height="30" border="0" alt="" style="display:block;" /></a>
                    <a  id="topstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="topst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

                    <a  id="bottom" target="main" style="float: left;margin-left: 5px; margin-top: 5px"><img class="img-responsive" src="bottom.png" width="22" height="30" border="0" alt="" style="display:block;" /></a>
                    <a  id="bottomstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="bottomst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

                    <!-- Set to Default postion
                     Switch on and switch off cam-->
                </div>
            </li>
        {{/each}}
    </ul>
    
    
</div>

#6

I see neither the video template declaration:

<template name="video">
  ...
</template>

neither the video template call:

  ...
  {{> video}}
  ...
</template>

#7

sorry i missed the preformatted text option… below are the lines above the section tag.

  <body style="background-color: #0b1c2f">

 </body>

  <template name="video">

where should I use the {{ > video}} call? I have not used it


#8

Pls note urlList is an array of objects formed in the server.js and is taken from the server result.


#9

Somewhere like this, I guess:

<body style="background-color: #0b1c2f">
  {{> video}}
 </body>

#10

Thanks. I have used this but still cant see the values inside the object e.g {{domainport}} is not visible in the html file. Below is the html code

<body style="background-color: #0b1c2f">
<section id="logo-section" class="text-center">
    <nav class="navbar navbar-fixed-left navbar-minimal animate" role="navigation">
        <div class="navbar-toggler animate" style="background-color: #7fff96; margin-top: 5px">
            <span class="menu-icon"></span>
        </div>
        <ul class="navbar-menu animate">
            <li>
                <a href="#snapshot" class="animate" id="singleCam">
                    <span class="desc animate"> Single Camera</span>
                    <span class="glyphicon glyphicon-stop"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="fourCam">
                    <span class="desc animate"> Four Cameras </span>
                    <span class="glyphicon glyphicon-th-large"></span>
                </a>
            </li>
            <li>
                <a href="#snapshot" class="animate" id="nineCam">
                    <span class="desc animate"> Nine Cameras </span>
                    <span class="glyphicon glyphicon-th"></span>
                </a>
            </li>
        </ul>
    </nav>
</section>

<div class="container" style="background-color: #c5c6c7; width: 90%; height : 90%">
    <ul>
        {{#each urlList1}}
            {{> video}}
        {{/each}}
    </ul>
</div>
</body>

<template name="video">
    <li>
        <img src="http://{{domainport}}/videostream.cgi?user={{camusername}}&amp;pwd={{campassword}}&amp;resolution=32&amp;rate=0" style="width: 49.5%; height: 49.5%; float: left"/>
        <div>
            <a  id="left" target="main" style="float: left; margin-top: 10px"><img class="img-responsive" src="left.png" width="30" height="2" border="0" alt="" style="display:block;" /></a>
            <a  id="leftstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="leftst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

            <a  id="right" target="main" style="float: left;margin-left: 5px;; margin-top: 10px"><img class="img-responsive" src="right.png" width="30" height="22" border="0" alt="" style="display:block;" /></a>
            <a  id="rightstop" target="main" style="float: left;margin-left: 5px;"><img class="img-responsive" src="rightst.png" width="39" height="39" border="0" alt="" style="display:block;" /></a>

        </div>
    </li>

</template>

BELOW IS THE HELPER FUNCTION#

Template.body.helpers({
        urlList1: function(){
            var urlList = [];
            var tokenId = '';

            tokenId = Cookie.get('Token');

            Meteor.call('cctvdetails', tokenId, function (error, result) {
                if (error) {
                    console.log(error);
                    //trigger an error message and raise an ALARM
                    //$('#autoclosable-btn-danger').prop("disabled", true);
                    $('.alert-autocloseable-danger').show();

                    $('.alert-autocloseable-danger').delay(5000).fadeOut("slow", function () {
                        // Animation complete.
                        // $('#autoclosable-btn-danger').prop("disabled", false);
                    });
                } else {
                    if (result == 'noDataReturnedByAPI') {
                        //$('#autoclosable-btn-warning').prop("disabled", true);
                        $('.alert-autocloseable-warning').show();

                        $('.alert-autocloseable-warning').delay(5000).fadeOut("slow", function () {
                            // Animation complete.
                            // $('#autoclosable-btn-warning').prop("disabled", false);
                        });
                    }
                    else {
                        $('.alert-autocloseable-success').show();

                        $('.alert-autocloseable-success').delay(5000).fadeOut("slow", function () {
                            // Animation complete.
                            // $('#autoclosable-btn-warning').prop("disabled", false);
                        });
                        urlList = result;
                        console.log('onRendered call: ' + urlList.length)
                        console.log('result domain port: ' + urlList);
                        var numberOfCameras = urlList.length;
                        Session.set('cameraCount', numberOfCameras);
                        if (numberOfCameras == 1) {
                            Session.set('templateType', 'singleCamView');
                        }
                        else if (numberOfCameras > 1 && numberOfCameras <= 4) {
                            Session.set('templateType', 'fourCamView');
                        }

                        else if (numberOfCameras > 4 && numberOfCameras <= 9) {
                            Session.set('templateType', 'nineCamView');
                        }
                        else if (numberOfCameras > 9) {
                            Session.set('templateType', 'moreThanNineCams');
                        }
                        console.log('inside the else: ' + urlList[1].domainport)
                        return urlList;
                    }

                }
            });


        }, })

THE SERVER METHOD CREATES THE URLLIST ARRAY LIKE BELOW

camList.push({
                    "domainport": domain+':'+port,
                    "camusername": username,
                    "campassword": password
                });

#11

i think… remove the var in the var camList in the server.js that way i think it will be treated as global variable… HTH


#12

It seems your urlList1 helper doesn’t return anything…


#13

i think I can now understand what is going wrong. Since the meteor.call from the client to the server is an asynch call, there is nothing returned by the urlList1: helper function when its called and the return urlList in the helper is called even before the values are returned by the meteor.call.

So an empty object is being passed to the html. Is there any i can make the urlList1 helperr function return the value only after the asynch call is complete?


#14

Check this post which reactively tracks the Meteor.call async callback in a helper. In that example (the second in the post), the call is made in the template’s onCreated callback, but it could be made elsewhere as long as the ReactiveVar is set up in the onCreated.


#15

thanks. what is the line of code
this.distinct = new ReactiveVar(); stand for? is distinct a variable that can hold an array of objects?


#16

I am referring to

Client

Template.getProjects.onCreated(function() {
  this.distinct = new ReactiveVar();
  Meteor.call('getDistinct', (error, result) => {
    if (error) {
      // do something
    } else {
      this.distinct.set(result); // save result when we get it
    }
  });
});

Template.getProjects.helpers({
  sites: function() {
    const projects = Template.instance().distinct.get();
    // turn our array of project values into an array of {project: project}
    return _.map(projects, project => {
      return {project}
    });
  }
});

<template name="getProjects">
  {{#each sites}}
    <div>Project: {{project}}</div>
  {{/each}}
</template>
Server

Meteor.methods({
  getDistinct: function() {
    return Meteor.wrapAsync(callback => {
      Sites.rawCollection().distinct('project', callback);
    })();
  }
});

#17

Yes. In that example, it’s a reactive variable holding an array. It doesn’t matter too much what you’re storing in there, as it’s really just being used for its reactivity - to re-run the helper when the method returns data.


#18

i am a bit confused with this code. I get the below error when I try to implement it in my code

Exception in delivering result of invoking ‘cctvdetails’: TypeError: Cannot read property ‘set’ of undefined
at http://localhost:3000/app/client/video/video.js?ce6054db903fbee769b230c9d0b3f133bf3906f8:47:42
at null._callback (http://localhost:3000/packages/meteor.js?431e407b21bf81d79061795e4fce958bea956e90:1007:22)
at _.extend._maybeInvokeCallback (http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:3508:12)
at _.extend.receiveResult (http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:3528:10)
at .extend.livedata_result (http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:4639:9)
at onMessage (http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:3373:12)
at http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:2742:11
at Array.forEach (native)
at Function.
.each.
.forEach (http://localhost:3000/packages/underscore.js?fa590de5090ceb4a42555b48562fd8f8e7035758:157:11)
at self.socket.onmessage (http://localhost:3000/packages/ddp-client.js?82da06d8e1ea6342d823b2c5c3be071e96108c70:2741:11)


#19

i think its failing in this line#

this.distinct.set(result);

am I missing anything for this exception to arise?


#20

distinct is the name of the ReactiveVar I used. You can call it anything you like, as long as it’s declared in Template.xxx.onCreated and referenced consistently elsewhere:

Template.xxx.onCreated(function() {
  this.anyname = new ReactiveVar();
  // ...
  this.anyname.set(someValue);
  // ...
});

Template.xxx.helpers({
  myhelper: function() {
    return Template.instance().anyname.get();
  });
});