Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Question: how to access task result from outside? #147

Open
jfoliveira opened this issue Jun 24, 2020 · 4 comments
Open

Question: how to access task result from outside? #147

jfoliveira opened this issue Jun 24, 2020 · 4 comments

Comments

@jfoliveira
Copy link

Hi,

Couldn't find in the docs a way to access the result of a task after the task is finished.
Example code that I tried without success:

async listItems() {
    const tasks = new Listr([{
        title: 'Loading items',
        task: async () => {
            const { data: items } = await someRemoteSlowApi.getItems();
            return items;
        }
    }]);

    const remoteItens = await tasks.run();
    console.log('returned items', remoteItens); // outputs `returned items [Object: null prototype] {}`
}

Is there any way to access the task result remoteItens value after the task has finished?

@jfoliveira
Copy link
Author

So, I made a new attempt to set variable values to the task context and try to access it from the outside, but I'm getting the error:
TypeError: Cannot destructure property 'myVariable' of '(intermediate value)' as it is undefined

I've just adapted the exitOnError test method and added a variable to the ctx.

Original code:
https://github.com/SamVerschueren/listr/blob/master/test/exit-on-error.js#L66

My adapted code - with changes highlighted in comments below:

const list = new Listr([
  {
    title: 'foo',
    task: () => Promise.resolve()
  },
  {
    title: 'bar',
    task: () => {
      return new Listr([
        {
          title: 'unicorn',
          task: () => Promise.reject(new Error('Unicorn failed'))
        },
        {
          title: 'rainbow',
          task: (ctx) => {
// CHANGE 1: set ctx property to be accessed from outside the task after the task finishes
            ctx.myVariable = 'my value';
            Promise.resolve();
          }
        }
      ], {
        exitOnError: false // CHANGE 2: I need task `rainbow` to be executed regardless of `unicorn` failing
      });
    }
  },
  {
    title: 'baz',
    task: () => Promise.resolve()
  }
], {
  exitOnError: false // CHANGE 3: not sure if needed, but also tried setting it to `true`
});
try {
  // CHANGE 4: attempt to access the value of `myVariable` that I expected to be in the `ctx`/task result
  const { myVariable: listResult } = await list.run().catch(error => { });
  console.log('list result', listResult);
} catch (error) {
  console.log('Task list failed', error);
}

The above code outputs:
TypeError: Cannot destructure property 'myVariable' of '(intermediate value)' as it is undefined

What am I doing wrong?

@verheyenkoen
Copy link

I guess you can chain off a .then() method and work with the returned context there, like so:

list.run()
    .catch(error => { /* … */ })
    .then(ctx => {
        console.log(ctx.myVariable)
    })

Don't know if you can achieve this with async/await.

@verheyenkoen
Copy link

Turns out it can work with async/await.

You should be able to do this but just await the result of list.run() and drop the .catch(…) chain as this is handled in the catch block (from inside an async function obviously):

try {
  const { myVariable: listResult } = await list.run();
  console.log('list result', listResult);
} catch (error) {
  console.log('Task list failed', error);
}

@sarink
Copy link

sarink commented Apr 11, 2022

Use listr2 https://github.com/cenk1cenk2/listr2 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants