SOLVED - Meteor.call returns Undefined


#1

Meteor.call returns undefined.
I do not see why.

  1. I wish to return an object. Could it be because of the method return syntax? I also tried ({}).

  2. Could it be because internal JSON like that has a slightly different syntax between Meteor and Vue.js or JavaScript?

Thanks, Marc

If I replace the call by a value, my value is assigned to the variable
(SEE: //HERE IS THE CALL):

main.js

import { Meteor } from 'meteor/meteor'  //server methods

//import 'vue-clicky'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

import VueMeteorTracker from 'vue-meteor-tracker'
Vue.use(VueMeteorTracker)
Vue.config.meteor.freeze = true

import GrapherVue from 'meteor/herteby:grapher-vue'
Vue.use(GrapherVue)

import lodash from 'lodash'
_ = lodash

const store = new Vuex.Store({
  state: {
    appStruc:{},
    count: 10
  },

  mutations: {
    increment (state) {
      state.count++
    },

    loadAppStructure(state) {
        state.appStruc=Meteor.call('appStructure')    //HERE IS THE CALL
    },
  }
})


new Vue({
	el: '#app',
    store,                     //inject store in all children components
	render: h => h('layout')
})

store.commit('loadAppStructure')         //HERE IS THE CALL

/server/ServerMethods)

Meteor.methods({ 

appStructure() {
    return ({
     root:[
       {i:'head', style: {gridArea:'head',   
        backgroundColor:'#00ff00',
        gridArea:'1/1/1/4'}}, 

       {i:'leftSideBar',style: 
       {gridArea:'leftSideBar',backgroundColor:'#0000ff',
        gridArea:'2/1/3/2', width:'200px', height:'400px'}},

       {i:'middle',style:{gridArea:'middle',backgroundColor:'#ffff00',
        gridArea:'2/2/3/3',width:'auto'}},

       {i:'rightSideBar',style:   
       {gridArea:'rightSideBar',backgroundColor:'#b0a0a0',
        gridArea:'2/3/3/4', width:'200px', height:'200px'}},

       {i:'footer',style:{gridArea:'footer',backgroundColor:'#a0c0a0',
        gridArea:'3/1/4/4'}}
      ]
})},

});

Could it be because I do not include the method module the right way?
I do:
import { Meteor } from 'meteor/meteor' //server methods

but the file is in server side anyway. I suppose Meteor includes all server folders automatically. Is it the real purpose of this line?


#2

Meteor method calls initiated on the client are asynchronous: https://docs.meteor.com/api/methods.html#Meteor-call

You can sort of simulate synchronicity using async/await and a package like https://github.com/deanius/meteor-promise. That package gives you a Meteor.callPromise function so you could do let result = await Meteor.callPromise(...).


#3

If you want to create Meteor.callPromise yourself, this is what Qualia uses:

Meteor.callPromise = function() {
  let args = Array.prototype.slice.call(arguments);
  return new Promise((resolve, reject) => {
    args.push(function(error, result) {
      if (error) {
        reject(error);
      }
      else {
        resolve(result);
      }
    });
    Meteor.call.apply(this, args);
  });
};

#4

Thanks, but the simple way is for “immediate execution” not doing something before it is executed. I suppose it should work as I coded it.


#5

It is not possible due to the nature of browser HTTP and WebSocket API


#6

What is not possible? It does not make sense that meteor.call does not work? I just wish to ask the server for some JSON data.


#7

Imagine you made a GET request to the server requesting some JSON data. That call wouldn’t return synchronously; it has to wait on a response from the server. Meteor methods behave the same way.


#8

#9

Getting an immediate value is not possible if you’re asking for that.

What you have to do on client is;

Meteor.call("appStructure", (err, result) => {
  console.log(result);
})

There is no other way to get a sync value from this method. It is absolutely impossible due to the nature of browser APIs as I said before. This doesn’t show that Meteor.call doesn’t work or something else. This is an expected behavior, you have to read some about promises, callbacks, HTTP requests on browser client etc.


#10

Fine, but my problem now is that the method is not found on the server. I suppose something is wrong in declarations or where the file is:

I have put in a /server folder, a file named ServerMethods:

Meteor.methods({ 

   appStructure() {
       return ({
          root:[
          {i:'head', style: {gridArea:'head',   
           backgroundColor:'#00ff00',
           gridArea:'1/1/1/4'}}, 

          {i:'leftSideBar',style: 
          {gridArea:'leftSideBar',backgroundColor:'#0000ff',
          gridArea:'2/1/3/2', width:'200px', height:'400px'}},

          {i:'middle',style:{gridArea:'middle',backgroundColor:'#ffff00',
          gridArea:'2/2/3/3',width:'auto'}},
  
          {i:'rightSideBar',style:   
          {gridArea:'rightSideBar',backgroundColor:'#b0a0a0',
          gridArea:'2/3/3/4', width:'200px', height:'200px'}},

          {i:'footer',style:{gridArea:'footer',backgroundColor:'#a0c0a0',
          gridArea:'3/1/4/4'}}
         ]
       })},
});

and in main.js:
import { Meteor } from 'meteor/meteor'

Great news: now it works, I had to put .js extension to the file. Thanks to all for helping leading to the solution.