Как использовать Meteor.settings в компоненте React

У меня есть компонент React, который выполняет вызов API при инициализации на стороне клиента. Я не хочу жестко кодировать свой ключ API (не дай Бог в репо), и не намного лучше поместить его в Meteor.settings.public, поскольку его можно просто посмотреть в консоли. Я хочу сохранить его в Meteor.settings, но тогда он будет невидим для клиента. Я пытался использовать метод, но, хотя он работает на сервере, вызов метода возвращает undefined на клиенте.

На сервере:

Meteor.methods({
  getFileStackAPIKey: function () {
      if (Meteor.settings.fileStackAPIKey) {
          console.info(Meteor.settings.fileStackAPIKey) // returns: [fileStackAPIKey] correctly
          return Meteor.settings.fileStackAPIKey
      }
      else {
          return {message: "Configure Meteor.settings.fileStackAPIKey to connect to FileStack."}
      }
  }});

На клиенте:

console.info(Meteor.call('getFileStackAPIKey')); // returns: undefined

Я попытался использовать ReactiveVar, и он снова установил его на сервере, но был недоступен на клиенте. У меня такое чувство, что я упускаю что-то очевидное. В частности, я пытаюсь заставить работать FileStack. В их примере кода ключ API жестко запрограммирован. Как и официальный пакет FileStack React. Это просто не кажется хорошей идеей.

🤔 А знаете ли вы, что...
React использует язык JavaScript для разработки компонентов пользовательского интерфейса.


61
1

Ответ:

Решено

Это связано с обратными вызовами. Результат метода будет в обратном вызове, поэтому то, что мне нужно было сделать на клиенте, было примерно таким:

Meteor.call('getFileStackAPIKey', (err, res) => {
    console.info("FileStack API Key: " + res);
});

Но поскольку я действительно хотел передать его в инициализацию FileStack (опять же, на стороне клиента), мне нужно было поместить следующее в конструктор для объекта FileStack:

// "this" is the FileStack object we're constructing
const fileStackObj = this;
Meteor.call('getFileStackAPIKey', (err, apiKey) => {
    // here we're inside the callback, so we have the resulting API key
    const client = filestack.init(apiKey, clientOptions);
    // these are synchronous actions dependent on the existence of "client"
    // that we could not do outside of the callback
    fileStackObj.state = {
        client,
        picker: action === 'pick' ? client.picker({ ...actionOptions, onUploadDone: fileStackObj.onFinished }) : null,
    };
    fileStackObj.onFinished = fileStackObj.onFinished.bind(fileStackObj);
    fileStackObj.onFail = fileStackObj.onFail.bind(fileStackObj);
});