0

Let's say my API returns a list of dates a product was viewed for simplicity. Some of the products were never viewed, and an empty list will be returned. When this happens, I want to show:

This product hasn't been viewed yet!

and hide the table with product view dates. I do this in the controller returning IHttpActionResult:

if (itemViewedDto.Count > 0)
{
     return Ok(itemViewedDto);
}
else
{
    return Ok(new {message = "No data"}); 
}

On the client I do (itemViewed is just the http response payload):

    $scope.dataExists = function(){
        if($scope.itemViewed.hasOwnProperty(message)){
            return true;
        } else {
            return false;
        }
    }

And then show response accordingly using ng-if or whatever to see if there was a response or not?

Is there anything wrong with this? Is this an accepted pattern? If not, what's a better way to do it? I am asking conceptually, not for this particular situation.

Currently its work for me, just I'm curious to know if it's wrong.

2
  • I suppose I could simply check for whether or not the response is empty, but someone told me to make the message property. Essentially I am wondering if that part is wrong. Commented Jun 20, 2015 at 19:00
  • I find this ugly. Why not just return always the same thing: an itemViewDto. If the UI layer wants to display a different message and hide a table when the list is empty, it just has to test if the list is empty. See api.github.com/search/… for example, which lists all the github repositories named dfsdfsdfsdfsdfsdfsdfsgfgqfgqdgsdfqfqsfqsfqsfqsfqsf Commented Jun 20, 2015 at 19:13

2 Answers 2

1

Make use of proper HTTP Status Codes and return a 204 No Content. WebApi doesn't provide a "NoContent" result, but you can provide one very easily with a "NoContentResult" class. This way you can stick with IHttpActionResults and not fall back to HttpResponseMessages.

public class NoContentResult : OkResult
{
    public NoContentResult(ApiController controller) : base(controller) { }

    public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = base.ExecuteAsync(cancellationToken).Result;
        response.StatusCode = HttpStatusCode.NoContent;
        return Task.FromResult(response);
    }
}

And now to use it and your status code will be set with an empty body:

if (itemViewedDto.Count > 0)
{
    return Ok(itemViewedDto);
}
else
{
    return new NoContentResult(this);
}

If you are using a base class for all your controllers, you can add this to your base class and then it will feel just like an Ok response.

public abstract class BaseApiController : ApiController
{
    /// <summary>
    /// Returns a No Content response.
    /// </summary>
    protected NoContentResult NoContent()
    {
        return new NoContentResult(this);
    }
}

Now you can use it like this:

if (itemViewedDto.Count > 0)
{
    return Ok(itemViewedDto);
}
else
{
    return NoContent();
}

Now in your JavaScript you can respond to different status codes rather than parsing the body.

Sign up to request clarification or add additional context in comments.

Comments

1

Personally I would avoid returning two different types of responses on a successful API call. It looks smelly, and serves absolutely no purpose. Just return a list, even if it is an empty list. On the Angular side just check if the array is empty or not and do your display logic based on that.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.