1

I have to get an argument value from the function inside the onlick property of a button, but the function (this.getListItemId(itemId)) which makes use of this argument is not inside of the context from where the button is. The button is inside a child function (this.renderVideoListTemplate()) which is inside a parent function (getVideoListItems()). The function i want call on the onclick event (this.getListItemId()) it is outside from where the function of the button (this.renderVideoListTemplate()) is, so it says the function (this.getListItemId(itemId)) does not exists.

var getVideoListItems = function() {
    var self = this;

    this.renderVideoListTemplate = function(result) {      

        for(let i=0; i < result.length; i++){  
    ====>>> var listItems ="<div class='Button fecharVideo' onclick='"+self.getListItemId(result[i].ID)+"'>"+ 
                                "<span class='Button'>Excluir Vídeo</span>"+
                            "</div>";

            $("#video-list-container").append(listItems);
        };
    };

    this.deleteListItem = function(webUrl, listName, itemId, success, failure) {
        self.getDataByItemId(webUrl,listName,itemId,function(item){
            $.ajax({
                url: item.__metadata.uri,
                type: "POST",
                headers: {
                    "Accept": "application/json;odata=verbose",
                    "X-Http-Method": "DELETE",
                    "If-Match": item.__metadata.etag
                },
                success: function (data) {
                    success();
                },
                error: function (data) {
                    failure(data.responseJSON.error);
                }
            });
        },
       function (error) {
           failure(error);
       });
    };

    this.getListItemId = function(itemId){
        self.deleteListItem(webUrl, listName, itemId)
    };

    return this.init();
}
isherwood
  • 58,414
  • 16
  • 114
  • 157
Arthur Muller
  • 61
  • 2
  • 10
  • Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Heretic Monkey Apr 24 '19 at 13:29

3 Answers3

1

You cannot assign a function reference within the string value of an onclick attribute.

You could avoid the issue and improve the logic by instead using a delegated event handler. You can keep the result[i].ID in a data attribute on the div you create which can be read when the click event happens. Try this:

// in your object:
this.renderVideoListTemplate = function(result) {
  var divs = result.map(function() {
    return `<div class="Button fecharVideo" data-id="${this.ID}"><span class="Button">Excluir Vídeo</span></div>`
  });
  $("#video-list-container").append(divs);
};

// somewhere else in your codebase:
$('#video-list-container').on('click', '.fecharVideo', function(e) {
  e.preventDefault();
  yourObjectReferece.getListItemId($(this).data('id'));
})

Also note the use of map() to build an array of strings to append to the #video-list-container element once, instead of within every iteration.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
1

First of all when witing: <a href'#' onclick='this.getListItemId(itemId)'>... this. will refer to the Object(HTMLElement) a who has the function.

Second: Best way to use listener is to use the .addEventListener FUNCTION such: document.querySelector('#id_of_element').addEventListener('click', function(e){ //-- do something with e arg is the event })

Using element.addEventListener(... separate code from the HTML , way clearer and easy to manipulate and use. By the way use named function allow you to removeEventListener that will erase behaviour and lighten code way to go.

jean3xw
  • 121
  • 7
1

I see you are using jQuery here, instead of using simple string you can create a jQuery element and add a listener with $().on()

So, this for loop:

        for(let i=0; i < result.length; i++){  
    ====>>> var listItems ="<div class='Button fecharVideo' onclick='"+self.getListItemId(result[i].ID)+"'>"+ 
                                "<span class='Button'>Excluir Vídeo</span>"+
                            "</div>";

            $("#video-list-container").append(listItems);
        };

can be transformed in the following one:

        for(let i=0; i < result.length; i++){  
            var listItems = $("<div class='Button fecharVideo'><span class='Button'>Excluir Vídeo</span></div>");
            listItems.on('click', function (){
                self.getListItemId(result[i].ID);
            });

            $("#video-list-container").append(listItems);
        };
Sergiu Pirlici
  • 140
  • 2
  • 13
  • The `on()` method isn't really needed here. `click()` would do fine. – isherwood Apr 24 '19 at 13:47
  • @isherwood, it is a matter of preference here, .click method is a shortcut for .on( "click", handler ), you can read the docs https://api.jquery.com/click/ – Sergiu Pirlici Apr 25 '19 at 13:03
  • Yep. I use `on()` when I need event delegation or when I need to handle multiple event types. Otherwise, shorthand methods such as `click()`, `blur()`, etc. seem cleaner. – isherwood Apr 25 '19 at 13:19