1

Hi I've been trying to clarify this but there's something I'm still confused about. I know that you can't return values from asynchronous functions so I've referenced this answer's top answer Returning value from asynchronous JavaScript method?

What I'm trying to do is use the flickrAPI to get the biggest size image. The flickrAPI allows one to search images, so I use this to get the photo_id, then I use this photo_id to procses another request to the API's getSize method to get the URL for the biggest size photo.

The code looks a little messy as it is, because I have a method called flickrRequest which sends an XMLHttp request and gets back a JSON string. I know that I can achieve what I want by writing the functions as follows:

function flickRQforimage() {
    ...got ID
    function flickrRQforSize() {
        ...got maxsizeURL
        create image based on maxsizeURL here
    }
}

but I was wondering if it was possible to do something like this

function flickRQforimage() {
    ...got ID
    function flickrRQforSize() {
        ...got maxsizeURL

    }
    create image based on maxsizeURL here
}
or even create image based on maxsizeURL here

In general my question is whether it is possible to have a callback function that references another statically defined function (I think?). The specifics of the my function is that it takes a callback and the ID and URL processing happens in those callbacks:

flickrRQ(options, cb) 

I am wondering whether/what would happen if that unnamed function is instead something else, say flickrRQ(options, processPhoto(data)), and then I define the function in a separate method. This just makes sense for me because I want to keep functionality for the URL processing separate in an attempt to make my code cleaner and more readable.

I tried the following below and it didn't work. Nothing prints. I even have a console.log in the processPhoto method. In fact anything inside of the flickrRQforSize method seems to not evaluate

flickrRQforSize(options, function(data) {
    processPhoto(data)
}

even though in the flickrRQforSize definition, a callback function is taken as an argument. I'm suspecting there must be something about functions/async calls that I don't understand.

I hope this is clear -- if not, I can post my actual code.

Here's my code:

var flickrRequest = function(options, xhrRQ, cb) {
    var url, xhr, item, first;
    url = "https://api.flickr.com/services/rest/";
    first = true;

    for (item in options) {
        if (options.hasOwnProperty(item)) {
            url += (first ? "?" : "&") + item + "=" + options[item];    
            //parses to search equest; 
            first = false;
        }
    }
    //XMLHttpRQ to flickr
    if(xhrRQ == 1 ) { 
        xhr = new XMLHttpRequest();
        xhr.onload = function() { cb(this.response); };
        xhr.open('get', url, true);
        xhr.send();
    };
}

var processPhotoSize = function(photoJSON) {
    var parsedJSON = JSON.parse(data); 
    var last = parsedJSON.sizes.size.length;
    console.log(parsedJSON.sizes.size[last-1].source);
    return parsedJSON.sizes.size[last-1].source;
}
...
flickrRequest(options, 1, function(data) {
    ...
    flickrRequest(sizesOptions, 0, function(data) {
            parsedJSON = JSON.parse(data);
            console.log(parsedJSON); 
            processPhotoSize(data); 
        });         
}
Community
  • 1
  • 1
frei
  • 495
  • 3
  • 19
  • Yes, it is possible, and quite common. Just make sure to hardcode the callback only when it is an essential part of the function, to still maintain separation of concerns. – Bergi Jun 19 '15 at 03:35
  • Your `flickrRQforSize` looks fine (except for the missing closing `)`), so if it doesn't work you should show us the rest of your code in a less pseudecode-like format. – Bergi Jun 19 '15 at 03:36
  • posted relevant code: i just noticed that i'm doing xhr.onload = function() { cb(this.response); }; which might have something to do with it? also right now you see a "return" in the processPhotoSize function and it shouldn't be there, but even so the console.log in that function doesn't trigger – frei Jun 19 '15 at 03:41
  • 1
    Uh, what is this `xhrRQ` parameter and what does it mean when it's set to `0`? In your second `flickrRequest` call, `cb` will never be called back. – Bergi Jun 19 '15 at 03:46
  • 1
    The `return` in `processPhotoSize` is totally fine, as it is a synchronous function. Only it's caller needs to do something with the result, and consume it as a return value in this case. – Bergi Jun 19 '15 at 03:48
  • 1
    @Bergi the xhrRQ param I used because I do the URL creation in there and use that URL somewhere else without actually sending an http request. so I do flickrRequest(options, 0) when I just want the URL. I should definitely separate those methods – frei Jun 19 '15 at 03:50
  • @Bergi `xhrRQ` appear to be `1` at `flickrRequest(options, 1, function(data) {` ? – guest271314 Jun 19 '15 at 03:50
  • @Bergi oh I see, that was really silly of me. but in general this would work? – frei Jun 19 '15 at 03:52
  • Wait actually I'm so wrong. I should delete this question. It should be 1 both times because the cb should only be called if JSON is returned, and JSON is returned and parsed in this method. Not sure why I got stuck. – frei Jun 19 '15 at 03:54
  • 1
    @guest271314. Not in `flickrRequest(sizesOptions, 0, function(data) {` – Bergi Jun 19 '15 at 03:55
  • @frei: Yes, you should absolutely separate those methods. – Bergi Jun 19 '15 at 03:55

0 Answers0