1

I've done all sorts of reading on promises and module creation and I can't figure out why this won't work.

I'm writing a script that takes a username and then uses a separate module to get user data from a 3rd party API. I can get everything to work fine when its put into the same script, but I'm doing something wrong when I pull out and separate the API request into its own module. These are built with durandal as a framework.

The script:

define(function(require) {
var http = require('plugins/http'),
    ko = require('knockout'),
    apiPullMod = require('apiPullMod');

return {
    name: ko.observable('RyeBrush'),
    nameInfo: ko.observableArray([]),
    getSummoner: function() {
        var that = this;
        if (!that.nameInfo()) {
            return;
        } else {
            that.nameInfo.push(apiPullMod.apiCaller('v1.4/summoner/by-name', that.name(), 'na'))
        };
        console.log(that.nameInfo);
    }
};
});

The module:

define(['plugins/http'], function(http) {
return {
    apiCaller: function(apiType, apiUserId, region) {
        http.get('https://' + region + '.api.pvp.net/api/lol/' + region + '/' + apiType + '/' + apiUserId + '?api_key=282d6dcb-a047-4262-88d0-c53b0e28e6ef', 'jsoncallback').then(function(response) {
            console.log(response);
            return response;
        })
    }
}
});

I can see from the console that the API request is successful, I get the expecetd JSON object and everything seems to be working fine. However when I push it to the nameInfo array, what I get is this: c(), hovering over this in firebug gives me the file path to my knockout library.

When I try this:

 apiPullMod.apiCaller('v1.4/summoner/by-name', that.name(), 'na').then(function(response){
                that.nameInfo.push(response);
                console.log(response);
            })

The module won't load, I imagine because I don't have a then property written into the module itself. However when I read the documentation for durandal and requirejs in this context, it reads that I shouldn't need to?

If I had to boil it down, my question is: How do I format my module, and the script that calls it, to pass a JSON object from one to the other?

NOTE: I've included my personal API key in this question because I can reset it on demand. I'm not worried about my API traffic this early in my app development.

2 Answers2

1

If you change the apiCaller to return a promise it might work, like this

define(['plugins/http'], function(http) {
    return {
        apiCaller: function(apiType, apiUserId, region) {
            return http.get('https://' + region + '.api.pvp.net/api/lol/' + region + '/' + apiType + '/' + apiUserId + '?api_key=282d6dcb-a047-4262-88d0-c53b0e28e6ef', 'jsoncallback');
        }
    };
});

apiPullMod.apiCaller('v1.4/summoner/by-name', that.name(), 'na').then(function(response){
    that.nameInfo.push(response);
    console.log(response);
});
lagerone
  • 1,747
  • 13
  • 13
  • I'll try it when I get home later. I might also try to add a more robust promise library than just relying on durandal and require to make it all work. – Rich Robinson May 20 '15 at 13:41
  • THIS WORKED! Thank you! But why did it work? Why wouldn't passing the response back through return in a `.then` setup work out? I was hoping to add more functionality to it but it works for now. – Rich Robinson May 21 '15 at 08:43
  • 1
    I don't think I can explain how promises work in a comment. Here's a question with pretty good answers that might help you, http://stackoverflow.com/q/5316697/975720. – lagerone May 21 '15 at 18:32
0

Looks like the http plugin is using knockout's map plugin to automatically convert your response to observables. I recommend using jquery's http plugin or other.

Matthew James Davis
  • 12,134
  • 7
  • 61
  • 90
  • That is weird. Could be though your right, might explain the `c ()`value. Will convert to using jquery directly tonight. – Rich Robinson May 20 '15 at 14:04