Question

I have a table called Subscription and another table called Client I need the gender of the Client who owns the subscription every time I make an update. Here's my update script:

    function update(item, user, request) {
    var subscriptionId = item.id;
    var subscriptionActivitiesTable = tables.getTable("SubscriptionActivity");
    var userTable = tables.getTable("User");
    var activityTable = tables.getTable("Activity");
    var userGender = userTable.where({id: item.UserId}).select('Gender').take(1).read();
    console.log(userGender);
    activityTable.where({PlanId:item.PlanId, Difficulty: item.Difficulty}).read({
         success: function(results){
             var startDate = item.StartDate;
             results.forEach(function(activity)
             {
                var testDate = new Date(startDate.getFullYear(),startDate.getMonth(), startDate.getDate());
                testDate.setDate(testDate.getDate() + activity.Sequence + (activity.Week*7));
                subscriptionActivitiesTable.insert({SubscriptionId: subscriptionId, 
                ActivityId: activity.id, ShowDate: new Date(testDate.getFullYear(), 
                    testDate.getMonth(), testDate.getDate()), CreationDate: new Date()});

             })
         }
     });

     var planWeeks = 12;//VER DE DONDE SACAMOS ESTE NUMERO
     var idealWeight = 0;
     if (userGender === "Male")
     {
        idealWeight = (21.7 * Math.pow(parseInt(item.Height)/100,2));    
     }
     else
     {
         idealWeight = (23 * Math.pow(parseInt(item.Height)/100,2));  
     }

     var metabolismoBasal = idealWeight * 0.95 * 24;
     var ADE = 0.1 * metabolismoBasal;
     var activityFactor;
     if (item.Difficulty === "Easy")
     {
         activityFactor = 1.25;
     }
     else if(item.Difficulty === "Medium")
     {
         activityFactor = 1.5;
     }
     else
     {
         activityFactor = 1.75;
     }
     var caloricRequirement = ((metabolismoBasal + ADE)*activityFactor);
     activityTable.where(function(item, caloricRequirement){
         return this.PlanId === item.PlanId && this.Type != "Sport" && 
         this.CaloricRequirementMin <= caloricRequirement && 
         this.CaloricRequirementMax >= caloricRequirement;}, item, caloricRequirement).read({
         success: function(results)
         {
             var startDate = item.StartDate;
             results.forEach(function(activity)
             {
                for (var i=0;i<planWeeks;i++)
                {
                     var testDate = new Date(startDate.getFullYear(),startDate.getMonth(), startDate.getDate());
                     testDate.setDate(testDate.getDate() + activity.Sequence + (i*7));
                     subscriptionActivitiesTable.insert({SubscriptionId: subscriptionId, 
                     ActivityId: activity.id, ShowDate: new Date(testDate.getFullYear(), 
                     testDate.getMonth(), testDate.getDate()), CreationDate: new Date()});
                }
             })
         }
     })
     request.execute();
}

I tried the code above and clientGender is undefined. As you can see I want to use the gender to set the idealWeight.

Was it helpful?

Solution

The read() method expects a function to be passed in on the success parameter - it doesn't return the result of the query like you'd think.

Try something like this instead:

function update(item, user, request) {
    var clientTable = tables.getTable("Client");
    var clientGender = 'DEFAULT';
    clientTable.where({id: item.ClientId}).select('Gender').take(1).read({
        success: function(clients) {
            if (clients.length == 0) {
                console.error('Unable to find client for id ' + item.ClientId);
            } else {
                var client = client[0];
                clientGender = client.Gender;

                // since we're inside the success function, we can continue to 
                // use the clientGender as it will reflect the correct value
                // as retrieved from the database
                console.log('INSIDE: ' + clientGender);
            }
        }
    });

    // this is going to get called while the clientTable query above is
    // still running and will most likely show a value of DEFAULT 
    console.log('OUTSIDE: ' + clientGender);

}

In this sample, the client table query is kicked off, with a callback function provided in the success parameter. When the query is finished, the callback function is called, and the resulting data is displayed to the log. Meanwhile - while the query is still running, that is - the next statement after the where/take/select/read fluent code is run, another console.log statment is executed to show the value of the clientGender field outside the read function. This code will run while the read statement is still waiting on the database. Your output should look something like this in the WAMS log:

* INSIDE: Male
* OUTSIDE: Default

Since the log shows the oldest entries at the bottom, you can see that the OUTSIDE log entry was written sometime before the INSIDE log.

If you're not used to async or functional programming, this might look weird, but as far as I've found, this is now node works. Functions nested in functions nested in functions can get kind of scary, but if you plan ahead, it probably won't be too bad :-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top