简体   繁体   中英

How to return a result from Meteor.call method in client?

I'm calling a server method from my client side code via the Meteor.call() function.

But I get an undefined value when I try to pass the callback function's return value to a var within the onCreated function.

Looking at this solution the result is still only available within the scope of the callback:

https://stackoverflow.com/a/31661065/1829251

Also when I read the docs for Meteor-call it explains that the method is async which explains that the return value of the function can't be assigned to a variable:

https://docs.meteor.com/api/methods.html#Meteor-call

Question:

How can you return a result from Meteor.call method in client?

Code snippet of client side code:

import { Template } from 'meteor/templating';
import { Meteor } from 'meteor/meteor';
import { Datasets } from '../../../../api/datasets/datasets.js';
import { Constants } from '../../../../startup/constants.js';


import './rollup-history.html';
import './rollup-history.scss';

Template.rollup_history.onCreated(function() {


  this.historyDays = 7;


  this.rollupHistoryMECTitles = () => {

    let mecObjects = [];

    // Query the MEC calendar dates from AppConfiguration collection
    let method = Constants.Methods.getAppConfigCollectionFromKeyDateSorted;
    mecObjects = Meteor.call(method, Constants.AppConfigKeys.meccalendarInitialValues, this.historyDays, (error, result) => {
          if(error){
            console.log("Error retrieving MEC Dates" + error);
          }

          //Logging values here shows the values as expected
          console.log("MEC Dates in View" + JSON.stringify(result));
          return result;
      }
    );

    //logging value here shows undefined value
    console.log("mec objects: " + JSON.stringify(mecObjects));

    return mecObjects;


  };


});

Template.rollup_history.helpers({



  mecHeaderColumns: function() {

    return Template.instance().rollupHistoryMECTitles();
  },

});

The value of your mecObjects will always be undefined , because Meteor.call function doesn't return anything. Server's method call response (or error) will be passed to callback only, like in your code, actually: those error and result variables.

Because the return statement is in the callback and is unblock you can't return a method value like that. you can put it https://github.com/stubailo/meteor-reactive-method which will return the value but it must live inside a helper or reactive environment.

short answer:

define your Meteor.Method inside common code (code available to server and client) then use Meteor.apply with the option { returnStubValue : true }

mecObjects = Meteor.apply(method, [Constants.AppConfigKeys.meccalendarInitialValues, this.historyDays], { returnStubValue: true }, (error, result) => {
       if(error){
         console.log("Error retrieving MEC Dates" + error);
       }

       //Logging values here shows the values as expected
       console.log("MEC Dates in View" + JSON.stringify(result));
       return result;
   }
 );

console.log(mecObjects) //prints the client-side result of the meteor method

longer answer:

Meteor allows for Optimistic-UI which is simulating a server method on the browser. To enable this, define your Meteor.Method in common code (server + client space). This is useful because the user can see the UI updates faster since we don't need to make a server-round trip. 流星方法流程

Notice that in the picture above, the method call runs first on the client and later on the server. { returnStubValue: true } allows the caller to receive the method's return value from the client run

When writing a Meteor method, you can use this.isSimulation to specify what logic runs exclusively on client or server. Any code outside of this check runs in both .

流星方法的例子

Note that in the picture above that the server only runs console.log("hi i'm server") while only the browser runs console.log("hi i'm client") . Both run the code outside of the isSimulation check.

A few concerns:

  1. What if the server return value is different from the client return value?

    result != mecObjects so you will need to handle that situation properly.

  2. What if the client run fails? Does the server still run?

    Yes, the server still runs. However you can prevent server runs on client failures by adding another option, throwStubExceptions: true . This option will throw client exceptions which you can capture in a try catch.

  3. What if the client and server mongo updates are different?

    The server mongo changes override the client mongo changes.

see more at https://guide.meteor.com/methods.html and https://forums.meteor.com/t/how-to-return-value-on-meteor-call-in-client/1277/2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM