-1

I know this has been asked before, but I simply cannot figure out how to do this right.

So, the below code is obviously wrong in the sense that I am awaiting something in a query.

    // GET: /<controller>/
    [HttpGet]
    public new IActionResult Index()
    {
        var model = new List<Models.ViewModels.ApplicationUser.ListViewModel>();
        model = _userManager.Users.Select(u => new Models.ViewModels.ApplicationUser.ListViewModel
        {
            Id = u.Id,
            Email = u.Email,
            Name = u.GivenName + " " + u.SurName,
            RoleNames = await _userManager.GetRolesAsync(u)
        }).ToList();
        return View(model);
    }

This makes the following error show: "the "await" operator can only be used within an async lambda expression".

So, I finalize the query first and I make the lambda async:

    // GET: /<controller>/
    [HttpGet]
    public new IActionResult Index()
    {
        var model = new List<Models.ViewModels.ApplicationUser.ListViewModel>();
        // get users first, so I don't have to async something in a Select
        var users = _userManager.Users.ToList();
        // make the lambda asyc
        model = users.Select(async u => new Models.ViewModels.ApplicationUser.ListViewModel
        {
            Id = u.Id,
            Email = u.Email,
            Name = u.GivenName + " " + u.SurName,
            RoleNames = await _userManager.GetRolesAsync(u)
        }).ToList();
        return View(model);
    }

But then I get Cannot implicitly convert type 'System.Collections.Generic.List<System.Threading.Tasks.Task<Models.ViewModels.ApplicationUser.ListViewModel>>' to 'System.Collections.Generic.List<Models.ViewModels.ApplicationUser.ListViewModel>'

So basically (I guess) it says I have a list of Task of which I should get the result. But how do I get the result from this Task? Or better: what is the best way to go about this?

I've checked this and this and this without getting closer.

Arjan
  • 16,210
  • 5
  • 30
  • 40

1 Answers1

2

Your variable named model is of the type List<Task<ApplicationUser>>. To get a List<ApplicationUser> you just need to await all of the tasks. Also, right now the call to get all users is the blocking variant you can switch that out for ToListAsync. Try this instead:

[HttpGet]
public async Task<IActionResult> Index() {
    var model = new List<Models.ViewModels.ApplicationUser.ListViewModel>();
    // get users first, so I don't have to async something in a Select
    var users = await _userManager.Users.ToListAsync();
    // make the lambda asyc
    modelTasks = users.Select(async u => new Models.ViewModels.ApplicationUser.ListViewModel {
        Id = u.Id,
        Email = u.Email,
        Name = u.GivenName + " " + u.SurName,
        RoleNames = await _userManager.GetRolesAsync(u)
    }).ToList();
    var users = await Task.WhenAll(modelTasks);
    return View(users);
}
JSteward
  • 6,833
  • 2
  • 21
  • 30