More simple questions

17 views
Skip to first unread message

Paul Tiseo

unread,
Jul 6, 2013, 11:53:00 PM7/6/13
to cuj...@googlegroups.com

Sorry for continuously asking the simple questions, but I get an error doing this below. It seems like when.join() works, but when(promise).join() returns an error. The error message seems to be "Object #<Object> has no method 'join'".

 
 when(validateEmail(data.user))
   
.join (
       readTemplate
(__dirname + '/templates/signup_thankyou.html')
     
, readTemplate(__dirname + '/templates/signup_thankyou.txt')
     
, readTemplate(__dirname + '/templates/signup_internal.txt')
     
)
     
.then(
     
function(values) {
        console
.log('then');
     
}
   
)
   
.otherwise(
     
function(error) {
        console
.log('error: ' + error);
     
}
   
)

and

var validateEmail= when_fn.lift(
 
function (theEmail) {
    check
(theEmail).len(6,320).isEmail();
   
return { email: theEmail };
 
}
);



Charilaos Skiadas

unread,
Jul 7, 2013, 12:30:58 AM7/7/13
to cuj...@googlegroups.com
On Jul 6, 2013, at 10:53 PM, Paul Tiseo wrote:

> Sorry for continuously asking the simple questions, but I get an error doing this below. It seems like when.join() works, but when(promise).join() returns an error. The error message seems to be "Object #<Object> has no method 'join'".

Right, it's the "when" object that has the join method, not the promise object you get back from when(validateEmail(data.user)).

I'm not entirely sure what you are trying to do, but I would venture to guess that, assuming readTemplate is another promise-producing function, that what you want is to join together the 4 promises starting with validateEmail(…). so something like the following?

when.join(
validateEmail(…),
readTemplate(….
readTemplate(…
….
).then(
...



>
> when(validateEmail(data.user))
> .join (
> readTemplate(__dirname + '/templates/signup_thankyou.html')
> , readTemplate(__dirname + '/templates/signup_thankyou.txt')
> , readTemplate(__dirname + '/templates/signup_internal.txt')
> )
> .then(
> function(values) {
> console.log('then');
> }
> )
> .otherwise(
> function(error) {
> console.log('error: ' + error);
> }
> )
>
> and
>
> var validateEmail= when_fn.lift(
> function (theEmail) {
> check(theEmail).len(6,320).isEmail();
> return { email: theEmail };
> }
> );
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "cujojs" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to cujojs+un...@googlegroups.com.
> To post to this group, send email to cuj...@googlegroups.com.
> Visit this group at http://groups.google.com/group/cujojs.
> To view this discussion on the web visit https://groups.google.com/d/msgid/cujojs/4ef94e91-20f6-4a5e-a5c1-8cb143869670%40googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Haris Skiadas

Paul Tiseo

unread,
Jul 7, 2013, 1:15:18 AM7/7/13
to cuj...@googlegroups.com
Haris:

Ah. I misunderstood that they would be chainable. So, most of the when.functions() are more like static methods of a when object in the OOP sense? So, how does when help me avoid the "callback pyramid" then? I guess it reduces it, but am I then having to nest all()s, join()s and parallel()s?

And,as for what I am trying to do is build a complex example to understand this library deeply. The simple examples in the docs are deceptive simple. :)  Not sure if it's better in a separate thread, but here's your typical webservice pseudocode:
1. setup data and validate some of it (call it checking pre-conditions)
2. do something async
3. do something sync with transformed data from step 3
4. do something different, async this time, and pass that along too
5. lastly, do one last thing

For example, slightly more tangible:
1. validate email
2. load three different template files (when.all() or when.join()?)
3. merge data (including that email) into those three templates separately
4. email each final item (all()? join()? when/parallel?)
5. save email to a database (then()?)

What started me down this road was that file reading, emailing and database access tend to be asynchronous in node.js, and so I was trying to manage that various callbacks (and styles) thereof, while guaranteeing that I handled exceptions, errors and the other inconsistencies in node.js, and ended up with robust code that wouldn't fall over itself when running behind my website.

Maybe I misunderstood and when.js isn't what I am looking for?

Charilaos Skiadas

unread,
Jul 7, 2013, 11:24:45 AM7/7/13
to cuj...@googlegroups.com
On Jul 7, 2013, at 12:15 AM, Paul Tiseo wrote:

>
> For example, slightly more tangible:
> 1. validate email
> 2. load three different template files (when.all() or when.join()?)
> 3. merge data (including that email) into those three templates separately
> 4. email each final item (all()? join()? when/parallel?)
> 5. save email to a database (then()?)


Hm let's see how I would structure this. First off, let's start with a function:

function readTemplate(templateName) {
// return promise for the template text
// Probably nodefn.call ?
}

Takes as input a filename, and returns a promise for the corresponding text. Then let's make a getTemplates function

function getTemplates() {
var templates = ["template1.txt", …. ];
return when.map(templates, readTemplate);
}

I suppose we have different ways to proceed now, what I am thinking however is this: Turn the templates into functions that given data input produce the substituted result. Most template engines offer you this compiled function step already, otherwise it might look something like this:

function compile(template) {
return function(data) {
// Merge data with template and return result
}
}

Then my getTemplates function would probably rather be:

function getTemplates() {
var templates = ["template1.txt", …. ];
return when.map(when.map(templates, readTemplate), compile);
}

now our getTemplates will be returning a promised array of functions. You also already have the method validateEmail which returns a promise. So then you can start the processing by something like:

parallel(getTemplates(), validateEmail())
.then(processForms) // handles item 4
.then(storeEmails) // handles item 5
.otherwise(handleErrors);

processForms might look something like this, taking as input the array of already substituted forms:

function processForms(forms) {
return parallel(when.map(forms, processSingleForm));
}
function processSingleForm(form) {
// Arrange to email the form, return promise
// The promise will either fulfill with what storeEmails expects, or reject if it fails to send
}

You get the idea I hope. You still will need a number of functions to do the individual parts in that large chain of steps you had, they just don't need to use callbacks, they can just expect a value for the most part, and return a value or promise. And you can more or less set up a single point of failure at the end of the chain of promises.

There's probably other ways around this question. That's my thinking of it as of the here and now.

Haris Skiadas

Reply all
Reply to author
Forward
0 new messages