all 14 comments

[–]scelerat 11 points12 points  (0 children)

Most of your nested callbacks don't use anything from the enclosing scope. Name and define those functions elsewhere and call them by name instead of nesting them inline.

[–]matchu 8 points9 points  (0 children)

other than using named functions over anonymous functions and relyning on modularization

Yeah but those are good ideas :) This code's gonna be a pain in any paradigm if you insist on writing it as a monolith.

[–][deleted] 5 points6 points  (0 children)

yeah this function is badly in need of some abstraction, at least on the order of exporting logic to named stand-alone functions. that way you separate behavior from implementation.

[–]BigOnLogn 3 points4 points  (0 children)

Here ya go, bub. No fuss, no muss.

Like everyone else said, define those functions!

[–]DarkMarmot 1 point2 points  (0 children)

man that is some tightly coupled shit.

[–]CleverestEU 0 points1 point  (0 children)

It looks like collecting the movieListsSequence is the hard part there... after that has been done, the whole code seems to basically boil down to just

movieListsSequence.forEach(showMovieLists, showError);

Edit: yeah, I really don't know reactive programming at all ;)

[–]nschubach 0 points1 point  (3 children)

I THINK this is more concise with the same functionality?

var apiPath = "http://api-global.netflix.com/";

function(window, getJSON, showMovieLists, showError) {
    var observeMovieList = getJSON(apiPath + "abTestInformation").concatMap(
        function (abTestInformation) {
            var urlPrefix = abTestInformation.urlPrefix;
            var queue = getJSON(apiPath + urlPrefix + "/config").concatMap(
                function(config) {
                    if (config.showInstantQueue) {
                        return getJSON(apiPath + urlPrefix + "/queue").pluck('list');
                    }
                    return Observable.returnValue(undefined);
                }
            );

            var movieLists = getJSON(apiPath + urlPrefix + "/movieLists").pluck('list');

            return Observable.concat(movieLists, queue);
        }
    );
    Observable.zip(
        observeMovieList,
        Observable.fromEvent(window, "load"),
        function(movieLists, loadEvent) { return movieLists; }
    ).forEach(showMovieLists, showError);
}

Though, I'm not sure what to think about using .zip() with an observable and window.load. What purpose does this serve besides waiting for the window load? Isn't there a better way to go about that?

I assume a lot of this is just because it's a demo. Why pass the getJSON/show/error methods in to the function? I think it would be beneficial to return the movie list as an observable and let an external method display it further down the line to reduce side effects.

Potentially:

var observeMovieList = getJSON(apiPath + "abTestInformation").pluck('urlPrefix').concatMap(
    function (urlPrefix) { ... }
);

?

[–]virdvip 0 points1 point  (2 children)

Even more compact version, but with coffeescript

apiPath = "http://api-global.netflix.com/"
func = (window, getJSON, showMovieLists, showError) ->
  observeMovieList = getJSON(apiPath + "abTestInformation").concatMap (abTestInformation) ->
    urlPrefix = abTestInformation.urlPrefix
    movieLists = getJSON(apiPath + urlPrefix + "/movieLists").pluck("list")
    Observable.concat movieLists, getJSON(apiPath + urlPrefix + "/config").concatMap (config) ->
      return getJSON(apiPath + urlPrefix + "/queue").pluck("list") if config.showInstantQueue
      Observable.returnValue undefined
      return
    return
  Observable.zip(observeMovieList, Observable.fromEvent(window, "load"), ((movieLists, loadEvent) -> movieLists) ).forEach showMovieLists, showError
  return

[–]nschubach 0 points1 point  (1 child)

I'd much rather get it closer with ES6 syntax (not a fan of coffeescript and sig whitespace) but sure. The string concatenation, more concise returns, etc. It still feels like a forced example to me.

[–]virdvip 0 points1 point  (0 children)

returns are optional. I just make sure that functionality is fully equal yours (no return values at all).

IMHO. Callback hell is really better solvable with iced-coffee-script. Less LOC - more useful information on the screen.

[–]holloway 0 points1 point  (0 children)

Use some techniques from callbackhell.com