Search code examples
mongodbmeteorpromisebluebird

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?


Solution

  • 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}`))
    }});