0

I have the following code:

In site-code.js

....

var ajaxContentFunc = $(origin).data("modal-content-handler");

$.when(window[ajaxContentFunc]()).done(function (resp) {
    kModal.showContent(resp);
});

In another file I have the following tag and function

<a href="#" data-modal-content-handler="ajaxContentGeneration">Click Me</a>

....

function ajaxContentGeneration() {

    var aProm = $.ajax({

        url: "tests/ajax/AjaxTest.aspx",
        data: { exampleType: "modal-ajax" },
        dataType: "html"


    });


    aProm.done(function (data) {

        console.log("Ajax Loaded!");
        var content = $(data).find("#ajax-content");

        return aProm;

    });


}

I need to populate the result of the ajaxContentGeneration (whatever method that might be) into the variable to send to showContent or in other words:

1) Pull the ajaxContentFunction Name from the tag's modal-content-handler data attribute

2) Call function (in this case ajaxContentGeneration)

3) Wait for the function's ajax to complete and return the data generated (in this case html)

4) When completed pass that value to kModal.showContent(----Here----);

However currently I am getting:

1) Pulls ajaxContentFunctionName correctly

2) Calls Function (ajaxContentGeneration() function)

3) Calls kModal.showContent(undefined). This is called prematurely because the deferred isn't correctly waiting for the function call to complete (after the ajax is done).

4) Ajax Completes

Where am I messing up here ?

Seth Duncan
  • 1,255
  • 2
  • 13
  • 31
  • 1
    what a mess... seems like some stuff are missing in your explanation. what is `(2) call function`. what function? where is this function `ajaxContentFunctionName` ? I am skeptical somebody could help.. – vsync Jul 07 '16 at 23:07
  • Sorry I was removing a whole bunch of extraneous stuff here and accidently renamed the requirement in the steps, so you are right it is a mess. I have adjusted to (hopefully) offer some more clarity. – Seth Duncan Jul 07 '16 at 23:22

2 Answers2

1

As far as I can tell, you are 95% there.

Use .then() instead of .done() and return the promise returned by $.ajax().then() :

function ajaxContentGeneration() {
    return $.ajax({
        url: "tests/ajax/AjaxTest.aspx",
        data: { exampleType: "modal-ajax" },
        dataType: "html"
    }).then(function (data) {
        return $(data).find("#ajax-content"); // this will return jQuery
        // return $(data).find("#ajax-content").html(); // this will return html
    });
}

You can probably also purge $.when() from the top-level call :

var ajaxContentFunc = $(origin).data("modal-content-handler");
window[ajaxContentFunc]().then(function (resp) {
    // `resp` is whatever was returned by the `return $(data).find()...` statement above
    kModal.showContent(resp);
});

The reason I say "probably" is that $.when() would be necessary if value-returning (not promise-returning) functions could be called instead of ajaxContentGeneration().

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
  • why `then` instead of `done` ? I think that has nothing to do with it. – vsync Jul 08 '16 at 12:35
  • I knew I was close, but as it always is, that last 5% is the one that makes you bash your head against your desk. Thank you. – Seth Duncan Jul 08 '16 at 15:34
  • 1
    @vsync, jQuery's `.then()` and `.done()` are (generally) not interchangeable. `.then()` returns a new Promise resolved with whatever its callback returns. `.done()` returns its input Promise unmolested. Here, the OP needs `.then()`. – Roamer-1888 Jul 08 '16 at 19:14
  • 1
    no, he should use `done` in this scenario. `then` shouldn't be used unless you want to create a new promise for some reason, which isn't the case here. Using `always` will act like `then`, but also shouldn't be used. `done` must work for HTTP status `200` – vsync Jul 08 '16 at 20:02
  • 1
    @vsync, think about it. If `.done()` was used, how would the line `return $(data).find("#ajax-content");` contribute to the Promise returned by `ajaxContentGeneration()`? It wouldn't. – Roamer-1888 Jul 08 '16 at 20:18
  • 1
    well it's all hose you view things, and what purpose you give to your functions what what future plans and other uses you would have for them.. I gave another answer now to show a different use. – vsync Jul 08 '16 at 20:48
1

Another way would be to do:

// should really be renamed...
function ajaxContentGeneration(){
    return $.ajax({
        url      : "tests/ajax/AjaxTest.aspx",
        data     : { exampleType: "modal-ajax" },
        dataType : "html"
    })
}

Somewhere else:

var ajaxContentFunc = $(origin).data("modal-content-handler");

window[ajaxContentFunc]()
    .done(function(RES){
        kModal.showContent( $(RES).find("#ajax-content") );
    });

So the functionality of the ajaxContentGeneration function will be to return an AJAX promise, and not have it manipulated inside it, but do the manipulation where needed (getting the #ajax-content element from the response)


Note that this whole thing is bad practice JS design, and you should avoid having functions on top of the window object, but instead on another object.

vsync
  • 118,978
  • 58
  • 307
  • 400