Unable to return queried API data in ASP.NET from repository

Viewed 41

I am trying to return JSON data from an API. The API endpoint is "/api/getUserSchedule(int id)". It should return back JSON data where it has been filtered according to the staffId value, which is a foreign key to the taskSchedule table.

I can return all the data, as shown here using a different API endpoint all API data

However, I need it to return data based on staffID. I have created an interface which is implemented by a repository.

interface code

public interface ITaskScheduleRepository
{    
  Task<TaskSchedule> GetUserSchedule(int id);  
}

Repository code

        public async Task<TaskSchedule> GetUserSchedule(int id)
    {
        var userTaskSchedule = await _context.TaskSchedules
        .Where(s => s.staffId == id)
        .ToListAsync();                                    

         return userTaskSchedule; // error is here            
    }

controller code

        [HttpGet("{id}")]
    public async Task<IActionResult> GetUserTaskSchedule(int id)
    {
        var taskUserSchedule = await _repo.GetUserSchedule(id);

        if(taskUserSchedule != null)
            return Ok(taskUserSchedule);            

        return BadRequest("There are no tasks for this user");     
    }

error message

Cannot implicitly convert type 'System.Collections.Generic.List' to 'Schedular.API.Models.TaskSchedule' [Schedular.API]csharp(CS0029)

2 Answers

You are trying to return a List<TaskSchedule> (note your .ToListAsync()) call in your repository method) but your interface is defined to return a single TaskSchedule. Update your interface and repository methods to return a List<TaskSchedule>

Task<IList<TaskSchedule>> GetUserSchedule(int id);

and

public async Task<IList<TaskSchedule>> GetUserSchedule(int id)

However, if a staff can only have one schedule, change your repository query to return a single item instead of a list of items.

var userTaskSchedule = await _context.TaskSchedules
    .Where(s => s.staffId == id)
    .FirstOrDefaultAsync();                                    

     return userTaskSchedule; /

You want 1 TaskSchedule instance, not a list of them which is what ToListAsync will return.

Change

public async Task<TaskSchedule> GetUserSchedule(int id)
{
    var userTaskSchedule = await _context.TaskSchedules
        .Where(s => s.staffId == id)
        .ToListAsync();                                    

    return userTaskSchedule;
}

To this

public Task<TaskSchedule> GetUserSchedule(int id)
{
    return _context.TaskSchedules.SingleOrDefaultAsync(s => s.staffId == id);
}

Note that I removed async/await because it is not necessary here. You can return the Task<T> instance directly to be awaited by the caller. If you need to do something with the returned instance before it is returned in this method then you can add back async/await and modify the instance before it is returned.

It is also considered good practice to add the word Async to the name of your methods as a suffix if a Task/Task is being returned. Example: GetUserScheduleAsync instead of GetUserSchedule.


Also you could also use FirstAsync, FirstOrDefaultAsync, or SingleAsync instead of SingleAsync. Which one depends on what your requirements are in the code.

Related