mboko
mboko

Reputation: 359

.then .done promises not working in durandal spa using knockout and js

I am working on a SPA developing in Durandal using Knockout jQuery and Require. My problem is when I make ajax calls to my API I don't actually get my data outside the .then statement(when I substitute my Get method with the line commented out below). However if i work with the current call I cannot use .then it gives me a type undefined error. I have looked at Durandal and they explain about using Q, I have it and referenced in my main. Not sure about the patches mentioned here

    var getSearchResult = function (dataHolder,text) {
            //return $.getJSON('/Api/Data/GetSearchItem/' + text).done();
            jQuery.support.cors = true;
            $.ajax({
                url: '/Api/Data/GetItem/' + text,
                type: 'GET',
                dataType: 'json',
                success: function (data) {
                    dataHolder(data);
                    var check = dataHolder();
                    return dataHolder();
                },
                error: function (e) {
                }
            });
        };

I call the method like so:

        var search = function (searchText) {
            dtx.getSearchResult(searchResult, searchText).then(function () {//(searchResult is an observableArray
                searchFlag(true);
                var test = searchResult();//i get data here
                searchTxt(searchText);
            });
            var test1 = searchResult();//no data here
        };

Upvotes: 1

Views: 511

Answers (2)

sroes
sroes

Reputation: 15053

What if you let getSearchResult return a promise?

var getSearchResult = function (dataHolder,text) {
        //return $.getJSON('/Api/Data/GetSearchItem/' + text).done();
        jQuery.support.cors = true;
        return $.ajax({
            url: '/Api/Data/GetItem/' + text,
            type: 'GET',
            dataType: 'json'
        }).then(function(data) {
            dataHolder(data);
            var check = dataHolder();
            return dataHolder();
        });
    };

Then also let search return that some promise:

    var search = function (searchText) {
        return dtx.getSearchResult(searchResult, searchText).then(function (data) {//(searchResult is an observableArray
            searchFlag(true);
            var test = searchResult();//i get data here
            searchTxt(searchText);
        });
    };

Now you could call search as follows:

search(searchText).then(function(data) {

});

Upvotes: 3

Jan Hommes
Jan Hommes

Reputation: 5152

getSearchResult does not return a promise. So you can not use q.js promise. There are two ways to solve this issue.

  1. The nice way: Implement your own promise resolver (see the q.js documentation. The Deferreds Part is what you are looking for)
  2. The fast way: Add a callback to your getSearchResult function and use this:

    var getSearchResult = function (dataHolder,text, callback) {
            //return $.getJSON('/Api/Data/GetSearchItem/' + text).done();
            jQuery.support.cors = true;
            $.ajax({
                url: '/Api/Data/GetItem/' + text,
                type: 'GET',
                dataType: 'json',
                success: function (data) {
                    callback(data);
                },
                error: function (e) {
                }
            });
        };
    

Then you can add a function as the callback:

        dtx.getSearchResult(searchResult, searchText, function (data) {
                //data contains the data from your ajax request.
                searchFlag(true);
                var test = searchResult();//i get data here
                searchTxt(searchText);
            });

Upvotes: 1

Related Questions