0

Often you need to pass "another" argument to a chained function, as well as the "results". How to do that?

Here's a Parse cloud code example:

var _ = require('underscore');
Parse.Cloud.define("doSomething", function(request, response)
    {
    var companyId = request.params.company;
    blah...

    companyFromCompanyId(companyId).then(function(company)
        {
        blah...
        return employeesFromCompany(company, kount);

    }).then(function(employees)
        {
        blah...
        // here, we would like to have passed in 'company' as an argument
        // as well as the "employees" result:
        ...  company.get("name") ...
        blah...
        }
        ,
        function(error) {blah...}
        );
});

So, with then(function(employees) I want to have "more arguments" coming in.

(Obviously, one could just make a variable in a bigger scope. In this question I am asking how to pass more arguments in to a .then)

Fattie
  • 27,874
  • 70
  • 431
  • 719
  • 1
    Looks like you already solved it; you need a variable in the shared scope. – Evan Davis Sep 09 '15 at 17:22
  • It's just strange that you ask us to not present it as a solution. You resolved company, so you -should- reuse it. – Léon Pelletier Sep 09 '15 at 17:25
  • @JoeBlow interesting; that's not actually what you're asking. If that were the question, the answer would be something in the area of partial application or binding. You are instead asking how to share scope from one result to another; a very different question indeed. – Evan Davis Sep 09 '15 at 17:35
  • See [Bluebird chain promises](http://stackoverflow.com/a/28714863/816620) for an example of four different techniques you can use to access previous promise results. – jfriend00 Sep 09 '15 at 23:47
  • Hi JFriend, thanks for that. the first three suggestions are naive, but the idea of nesting them -- interesting ?!?! can that be done, I didn't even know. surely it changes the "concept of" a promise?? – Fattie Sep 10 '15 at 00:23
  • exact duplicate of [How do I access previous promise results in a .then() chain?](http://stackoverflow.com/q/28250680/1048572)? – Bergi Sep 12 '15 at 14:40
  • Hi Bergi, thanks a million for pointing that out. FWIW I'd say the answer here by caas/banjamin is extremely clear and useful. (And it's possible the question is quite clear here, also - I just edited it again for ever-more clarity!) – Fattie Sep 12 '15 at 15:01
  • So I hope is [this answer](http://stackoverflow.com/a/28250693/1048572) (which is just one of the many possible approaches to solve the underlying problem, but gets you multiple arguments in your callback function) :-) – Bergi Sep 12 '15 at 15:11
  • That's ... too complicated for me :) – Fattie Sep 13 '15 at 14:59

1 Answers1

1

Updated as per comment from @BenjaminGruenbaum

    Parse.Cloud.define("doSomething", function(request, response) {
        var companyId = request.params.company;
        blah...

        companyFromCompanyId(companyId)
          .then(function(company) {
             return [employeesFromCompany(company, kount), company];
           })
          .spread(function(employees, company)
            {
              blah... // employees
              var theCompanyName = company.get("name");
              blah...
            })
          .catch(function(error) {blah...});
    });
caasjj
  • 1,354
  • 8
  • 11
  • Doesn't a `then` need to return a promise in order to be chainable? – Evan Davis Sep 09 '15 at 17:26
  • Oops. Yeah, that would need an array of promises and a defer to wait for two promises, one being a fake promise. Better defining "shared" variables at the main scope level. – Léon Pelletier Sep 09 '15 at 17:29
  • @Mathletics: No, `then` will automatically map the return to a promise. Try this in Chrome console: `Promise.resolve('done') .then(function(value) { return { value: value, data: 'new data' } }) .then( function(result) { return result }) .then(console.log.bind(console)) .catch(console.error.bind(console));` – caasjj Sep 09 '15 at 17:33
  • astounding; TBC `.spread` is "part of" `.then` .... or can you use `.spread` anywhere?? amazing tip, thanks. what a language! – Fattie Sep 09 '15 at 17:38
  • 3
    http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it – Benjamin Gruenbaum Sep 09 '15 at 18:21
  • @BenjaminGruenbaum thanks for pointing that out. Updated answer with a better pattern. – caasjj Sep 09 '15 at 19:13
  • even better now! whoa! you guys rock! – Fattie Sep 09 '15 at 22:18
  • don't worry i always, furthermore, send a bounty to good answers, see my history. notice above JFriend (link) suggests actually NESTING the .then items. To me that seems disturbing .. it would seem to change the "nature of" the .then, in ways I don't understand. – Fattie Sep 10 '15 at 00:24
  • Might as well use callbacks – caasjj Sep 10 '15 at 05:07
  • Got it. Assuming I follow you correctly, as I suspected the idea of "nesting" a promise would seem to completely abrogate the raison d'etre of promise. – Fattie Sep 10 '15 at 15:29
  • It's a common misconception that promises are there to alleviate 'callback hell', but that's just a side benefit. Promises are way more than that. Think of them as a tool to enable you to reason about *asynchronous* code the same way you do about *synchronous* code, where functions either return a value or throw an exception. Combined with generators, promises are just the bee's knees. – caasjj Sep 10 '15 at 15:53
  • that sounds incredibly insightful caasji, and makes a lot of sense. can you point me to something on *generators* in js? what is it? – Fattie Sep 10 '15 at 18:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89322/discussion-between-caasjj-and-joe-blow). – caasjj Sep 10 '15 at 18:57