object - Javascript - Error ... is not a function inside a closure -


this question has answer here:

in for-loop commented as:

// iterate on array , append each element li

... there closure works fine if put console.log(tags[x]); suggest closure works intended. however, when put actual code closure should contain, ie. this.displayimg(tags[x]); throws error. when click on li, get:

uncaught typeerror: this.displayimg not function (anonymous function) @ script.js:49 

please advise how can access this.displayimg place.

var mygallery = (function () {     var s;      return {         settings: {             data: json.parse(data),             filter: document.getelementbyid("filter"),             gallery: document.getelementbyid("gallery")         },         init: function () {             // kick things off             s = this.settings;             // default, call fillimages function 'all' tag             this.createfilters("all");         },         createfilters: function (tag) {             // load image data             // made imgs global couldn't access displayimg             imgs = this.settings.data.images;              // image tags , generate tag array             var tags = ["all"];              (var = 0; < object.keys(imgs).length; i++) {                 // check if tag in tags                 if (tags.indexof(imgs[i].tag) > -1) {                     // yes, is, don't add                 } else {                     // no, isn't, add 'tags'                     tags.push(imgs[i].tag);                 }             }             // create unordered list, assign class , append filter             var ul = document.createelement('ul');             ul.classlist.add("ul-bare");             this.settings.filter.appendchild(ul);              // iterate on array , append each element li             (var = 0; < tags.length; i++) {                 var li = document.createelement('li');                 ul.appendchild(li);                 li.innerhtml = tags[i];                 li.onclick = (function (x) {                     return function () {                         console.log(tags[x]);                         this.displayimg(tags[x]);                     };                 })(i);             }         },         displayimg: function (filter) {             // add images #gallery             (var = 0; < object.keys(imgs).length; i++) {                 var div = document.createelement("img");                 // if tage 'all', display images                 if (filter === "all") {                     div.src = imgs[i].src;                     this.settings.gallery.appendchild(div);                 } else {                     // display images of category (tag argument)                     if (imgs[i].tag === filter) {                         div.src = imgs[i].src;                         this.settings.gallery.appendchild(div);                     }                 }             }         }     }; })();  mygallery.init(); 

thank you

inside onclick, this reference dom element clicked, not this means you're hooking up.

if want access object this refers when you're setting handler, use variable:

var thisobj = this; (...) { 

...and in handler:

thisobj.displayimg(tags[x]); 

although in case, since don't need this refer handler, can make lot simpler function#bind:

for (var = 0; < tags.length; i++) {     var li = document.createelement('li');     ul.appendchild(li);     li.innerhtml = tags[i];     li.onclick = function(x) {         console.log(tags[x]);         this.displayimg(tags[x]);     }.bind(this, i); } 

function#bind returns new function that, when called, call original specific this value , further arguments give bind (followed arguments receives @ runtime).


side note: may pass tag in, rather index:

var thisobj = this; (var = 0; < tags.length; i++) {     var li = document.createelement('li');     ul.appendchild(li);     li.innerhtml = tags[i];     li.onclick = (function(tag) {         return function() {             console.log(tag);             thisobj.displayimg(tag);         };     })(tags[i]); } 

or

for (var = 0; < tags.length; i++) {     var li = document.createelement('li');     ul.appendchild(li);     li.innerhtml = tags[i];     li.onclick = function(tag) {         console.log(tag);         this.displayimg(tag);     }.bind(this, tags[i]); } 

Comments

Popular posts from this blog

sublimetext3 - what keyboard shortcut is to comment/uncomment for this script tag in sublime -

java - No use of nillable="0" in SOAP Webservice -

ubuntu - Laravel 5.2 quickstart guide gives Not Found Error -