apigee-127 / bagpipes

Less code, more flow. Let's dance!
MIT License
47 stars 30 forks source link

undefined context.output #10

Closed jcferrer closed 8 years ago

jcferrer commented 8 years ago

I am trying to use the geocoding example shown in the documentation. Geocoding works fine, but I cannot find a way to get the final results from the context.output property. It seems to be undefined. I can see it in the debug output, but console.log(context.output) returns undefined.

config/default.yaml

#1. Define a http callout we'll use in our pipe
 google_geocode:
   name: http
   input:
     url: http://maps.googleapis.com/maps/api/geocode/json?sensor=true  
     params:
       address: .request.parameters.address.value[0]

 #2. Defined the pipe flow we'll play
 getAddressLocation:
   - google_geocode            # call the fitting defined in this swagger
   - path: body                # system fitting: get body from output
   - parse: json               # body is a json string, parse to object
   - path: results             # get results from body
   - first                     # get first result
   - path: geometry.location   # output = { lat: n, lng: n }

app.js

'use strict';

var fs = require('fs');
var bagpipes = require('bagpipes');
var yaml = require('js-yaml');

var pipesDefs = yaml.safeLoad(fs.readFileSync('config/default.yaml'));
var pipesConfig = {};
var pipes = bagpipes.create(pipesDefs, pipesConfig);
var pipe = pipes.getPipe('getAddressLocation');

var context = {
    request: { 
        parameters: { 
            address: { 
                value: [ 'Frisco TX. 75034' ]
            }
        }
    }
};
pipes.play(pipe, context);

console.log(context.output);
theganyo commented 8 years ago

Hey JC. Sorry, that's completely my fault in documentation. pipes.play() actually executes asynchronously and so the console.log() won't log anything. The correct thing to do in this case would be to add a fitting to the end of the pipe that executes the console.log(). I'll update the docs.

That said, perhaps I should look into allowing the client to either pass an optional callback to the play() function or return a Promise that can be waited for so a client can respond outside of the pipe. What do you think?

jcferrer commented 8 years ago

Scott,

I was expecting it be asynchronous but I didn't see any callback function in the signature. Callback or promise would work.

Thanks for the help.

theganyo commented 8 years ago

Ok. But before I look into adding code for that... Would just adding an in-line fitting before calling play() work for you as well?

pipe.fit(function(context, cb) {
  console.log(context.output);
  cb(null, context);
});

pipes.play(pipe, context);

It should offer the same behavior as what you're expecting and I can just add some documentation for it.

jcferrer commented 8 years ago

Scott,

Yes that would work also. Thanks JC

theganyo commented 8 years ago

Great. So for now, I've updated the examples to work correctly. I'll also consider adding a Promise, callback, or event for when the pipe finishes execution.