0

I have never been very good at understanding JS callbacks, promises and all of these. Now I stumbled on one of these scenarios.

I have a text element. When clicked, it is made editable. When pressing enter, an AJAX request is made with the input value and then (here is my issue) the original text should be updated with the input.

$('#text-element').click(function() {
    edit($(this), url, paramName);
});

function edit($element, url, paramName) {
    // show the input, set up some UI events...

    $input.keypress(function(key) {
        // check if it is the correct key to submit the data
        if (submit) {
            var data = {};
            data[paramName] = $input.val();
            $.ajax({
                url: url,
                method: 'post',
                data: data,
                success: function(response) {
                    // ???
                }
            });
        }
    });
}

You could say: simple, just take the data from the response and replace the original text with the updated one. I can't/don't want to do that because I want the edit function to stay generic so it can be used in other scenarios, as you might have guessed by the use of the different arguments.

Also, in the context of the edit function we don't really know the shape of the response object, so we cannot handle it at that stage.

The right place where the response should be handled is the part where we click the text element, here we do know the context and we know the expected composition of the response.

So essentially, I would want to return (or whatever you do when dealing with promises, callbacks, async operations...) the response from the ajax success function, fetch that response in the click handler funtion and deal with it accordingly:

$('#text-element').click(function() {
    edit($(this), url, paramName); // <--- this should "return" the response
    var response = ...; // how do I fetch this response from the edit function
    $(this).html(response.content); // the response we expect in this case would be a JSON response with a key "content"
});

I hope I could make myself understand. If I don't, please let me know so I can clarify the question.

dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • Why are you bind event handler inside another event handler? – Satpal Apr 20 '17 at 12:56
  • What is `$input`? Regardless, the `$element` parameter will refer to the original text element. – nnnnnn Apr 20 '17 at 12:56
  • @Satpal I do not understand what you are asking. – dabadaba Apr 20 '17 at 12:58
  • @nnnnnn an input element as you might guess. Yeah, I know the $element will refer to the original text, so what is your point? – dabadaba Apr 20 '17 at 12:58
  • Why `$input.keypress(function(key) {})` inside the `$('#text-element').click()` handler – Satpal Apr 20 '17 at 13:00
  • @Satpal just listen to keypresses after the user has pressed the element. I dont know why this is so special? ( yes hes missing the 'does already exist' check etc. but its a start...) – Jonas Wilms Apr 20 '17 at 13:02
  • @Jonasw, Its special as a new event handler will be attached on every click – Satpal Apr 20 '17 at 13:04
  • So you could, say, trigger a custom event on that element, passing the result as data in the event. – nnnnnn Apr 20 '17 at 13:06

1 Answers1

1

Simply make a callback function:

$('#text-element').click(function() {
    edit($(this), url, paramName,function(response){
        this.html(response.content);
    }.bind($(this)));//bind to keep the #text-element as this
});

function edit($element, url, paramName,callback) {
// show the input, set up some UI events...

$input.keypress(function(key) {
    // check if it is the correct key to submit the data
    if (submit) {
        var data = {};
        data[paramName] = $input.val();
        $.ajax({
            url: url,
            method: 'post',
            data: data,
            success: function(response) {
                callback(response);//whats your problem with callbacks? they are so easy...
            }
        });
    }
});
}

By the way, if the user clicks twice, there are two keypress handlers registered, making the whole code a mess. So you may prevent that in a way...

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • `this` does not seem to be a jQuery at all, since I am calling `$el.width` in the `edit` function and I am getting the message "it is not a function", meaning it is not a jQuery instance. – dabadaba Apr 20 '17 at 13:14
  • @dabadaba oops, looks like youre right. edited – Jonas Wilms Apr 20 '17 at 13:19
  • @dabadaba nope. that should work based on the code youve posted.The err must be somewhere else... – Jonas Wilms Apr 20 '17 at 13:50