Q:

Using bluebird library in meteor to save data from remote API into local mongo db

Meteor.methods({
'sync.toggl'(apiToken) {

  const toggl = new TogglApi({ apiToken });

  Promise.promisifyAll(toggl);

  toggl.getWorkspacesAsync()
    .each(ws => toggl.getWorkspaceProjectsAsync(ws.id)
      .map(p => {
        Projects.upsert({ projectId: p.id }, {
          projectId: p.id,
          name: p.name,
          tracker: 'toggl',
          tags: [],
          contributors: []
        });
      })
      .catch(err => console.error(`fetching ${ws.name} projects error - ${err.message}`));
  )
  .catch(err => console.error(`fetching ${ws.name} workspace error - ${err.message}`));
}});

I'm trying to save data from toggl api into local db here. But Meteor throws an error - Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment. I found couple solutions, but they doesn't allow me to use bluebird promises... or not?

A:

Using async/await worked for me:
Meteor.methods({
'sync.toggl'(apiToken) {
  const toggl = new TogglApi({ apiToken });
  Promise.promisifyAll(toggl);

  async function saveProject(pid, name) {
    try {
      return await Projects.upsert(
        { pid },
        {
          pid,
          name,
          tracker: 'toggl',
          contributors: [],
        }
      )
    } catch (err) {
      return console.error(`async saveProject failed - ${err.message}`);
    }
  }

  toggl.getWorkspacesAsync()

    .each(ws => toggl.getWorkspaceProjectsAsync(ws.id)

      .map(p => {
        saveProject(p.id, p.name);
      })

      .catch(err => console.error(`fetching projects error - ${err.message}`))
    )
    .catch(err => console.error(`fetching workspaces error - ${err.message}`))
}});

