Pass a async result across templates

Hi guys, I get a MSSQL result in Template.cars.onCreated through async/await and callPromise and trying to pass this result to carDetails, but I get nothing but undefined in target template’s onCreated, onRendered and helpers.

If get rid of the async in Template.cars.onCreated, I am able to pass synchronous parameter even though it is a ReactiveVar.

I am wondering what kind of modification I should do for this case. All ideas are most welcome! Thanks

In cars.js

Template.cars.onCreated(async function () {
    this.reactiveSeekerData = new ReactiveVar();
    var carID= "123456";
    var self = this;
    var data = await Meteor.callPromise('MSSQLQuery', carID);
    self.reactiveCarData.set(data);
    return self.reactiveCarData.get();
    }
});

Template.cars.helpers({
    carsData:  function () {
        var instance= Template.instance();
        var data =  instance.reactiveCarData.get();
        console.dir(data); //Rusult is the correct result which is an object 
        return data;
    },
});

in cars.html

 {{> Template.dynamic template="carsDetails" data=carsData}}

in carsDetails.js

Template.carsDetails.onCreated( function() {
  var data = this.data;
  console.dir(data); //undefined
});

Template.carsDetails.onRendered( function() {
  var data = this.data;
  console.dir(data); //undefined
});

Template.carsDetails.helpers({
  exclamation: function() {
    var data = Template.instance().data;
    console.dir(data); //undefined
    return 0;
  }
});

I can’t see anything obvious which would prevent that working. There are a few changes I would make for syntax and redundant code. Otherwise, given the code you’ve shared, it should work (and in my independent test, it does).

Hi Rob, my friend told me the issue is the return value in the Template.cars.helpers.

var data = instance.reactiveCarData.get(); is returning a static get() value which should be replaced by
var data = instance.reactiveCarData; which is returning a reactive variable.

Hmm. Your friend is misinformed: instance.reactiveCarData.get() returns a reactive value (the current value in the reactive variable); instance.reactiveCarData returns a reference to the reactive variable, not the value.

Here’s a minor reworking of your code which should work - it works for me, but I obviously don’t have access to the rest of your code. I’ve fixed the issues I mentioned and used ES6 syntax.

Template.cars.onCreated(async function () {
  this.reactiveCarData = new ReactiveVar();
  const carID= "123456";
  const data = await Meteor.callPromise('MSSQLQuery', carID);
  this.reactiveCarData.set(data);
});

Template.cars.helpers({
  carsData() {
    const instance= Template.instance();
    const data =  instance.reactiveCarData.get();
    console.dir(data);
    return data;
  },
});

in carsDetails.js

Template.carsDetails.onCreated( function() {
  const data = this.data;
  console.dir(data);
});

Template.carsDetails.onRendered( function() {
  const data = this.data;
  console.dir(data);
});

Template.carsDetails.helpers({
  exclamation() {
    const data = Template.instance().data;
    console.dir(data);
    return data;
  }
});
1 Like

Hi Rob, I modified my code according to your suggestion but it didn’t work.

“MSSQLQuery” returns an array of object which I can get in “cars” perfectly.

Meteor.methods({
    async MSSQLQuery(carID) {
        var sql = require('mssql');
        let config = {
            user: "user_name",
            password: "password",
            database: "CAR",
            server: "localhost"
        };
        try {
            var query = 'SELECT * FROM [car] WHERE [car].[ID]=' + carID + ';';
            var connection = await sql.connect(config);
            var result = await connection.request().query(query);
            sql.close();
            return (result);
        } catch (error) {
            sql.close();
            return (error.message);
        }
    }
})

Now I have a workaround that I use Session to replace passing ReactiveVar across those templates. I know it may be not a wise choice but I still have no much confidence in Blaze template’s value passing. Thanks.