Pregunta

This is more a general JS question and not specific to edge.js. I wanted to play with SQL Server access via edge.js. Based on the following snippet from its GitHub site

var edge = require('edge');

var getTop10Products = edge.func('sql', function () {/*
    select top 10 * from Products
*/});

getTop10Products(null, function (error, result) {
    if (error) throw error;
    console.log(result);
    console.log(result[0].ProductName);
    console.log(result[1].ReorderLevel);
});

I wrote the following to access my own database:

var edge = require('edge');
var _    = require('lodash');


var thingsAccess = function () {/*
    select * from Things where Status = 'A' and Type=@thingType 
*/};

var getThingsList = edge.func('sql', thingsAccess);

var logResult = function (error, result) {
    if (error) throw error;

    _.each(result, function (thing) {
        console.log(thing.Id, thing.Category, thing.Name);
    });
};

var thingsOfType = function (type) {
    return function () { 
        getThingsList({ thingType: type }, logResult); 
    };
};


var xThings = thingsOfType('X');
var yThings = thingsOfType('Y');


xThings();
yThings(); 

My question is, how can I return results from logResult rather than just using the data inside that function? Instead of the _.each(result, ...) construct that now logs to the console, I'd rather have something like return _.map(result, ...) that returns an array of Thing objects. But because the function is a callback for getThingsList, I have nowhere to put the results.

Given how I have structured the code, it seems like my only option is to declare an array in the outer scope and push to it from inside logResult. I'm sure I'm doing it wrong, but I can't see how to restructure. Any suggestions?

¿Fue útil?

Solución

You can't "return" it, you have to work in a callback, just like the log function is doing.

var thingsOfType = function (type, onSuccess, onError) {
    getThingsList({ thingType: type }, function (error, result) {

        // Process if no error
        if (!error) {
            if (onSuccess instanceof Function) {
                onSuccess(result);
            }
            // silently do nothing if onSuccess is not a function
            return;
        }

        // Handle errors using the onError callback or throw
        if (onError instanceof Function) {
            onError(error, result);
            return;
        }

        // unhandled errors
        throw error;

    }); 
};

Now you can use it as Array or within each:

thingsOfType("X", function (result) {

    // Here result should be an Array
    var len = result.length;

    // You can use result here with or without _.each

    // Do something here

} /*, not an onError function defined */ );

Example Usage, and how to go further with the event driven code:

var printAllThingsOf = function (type, onSuccess, onError) {

   thingsOfType(type, function (result) {

       // Print each one
       _.each(result, function (thing) {
           console.log(thing.Id, thing.Category, thing.Name);
       });

       // this function is the thingsOfType-onSuccess function,
       // so propagate the new printAllThingsOf-onSuccess function;
       // "call the callback"
       if (onSuccess instanceof Function) {
           onSuccess(result);
       }

   }, onError /* propagate the onError */ );

};

printAllThingsOf("X"); // just do it or fail. onSuccess and onError are undefined.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top