How to call ServiceStack API end point from JavaScript

Standard

Why this is important? You might ask? Yes, it is straight forward and we all have done this several times. But why I thought of writing about this is because I wasted couple of hours because of a silly oversight. In the title I said API based on ServiceStack, this is nothing different from any other RESTful endpoint, ex: WebAPI.

So in my service takes an input like this:

[Route("/usermeta")]
public class UserMeta
    {
        public string Email { get; set; }
        public List<string> Expertise { get; set; }
    }

and service implementation goes something like this:

[Authenticate]
        public object Post(UserMeta request)
        {
        
            //I do something here
            
        }

Now to call this api, this is what we do in JavaScript world,

                    var request = { };
                   
                    request.Email = this.profileEmail;
                    request.Expertise = this.expertAreas(); //ERROR!!!
                   
                    $.ajax({
                        type: "post",
                        url: 'api/usermeta',
                        dataType: 'json',
                        data:request,
                        success: function (data) {
                            toastr.success("Everything is saved, you are all set for now!", 'Wohoo!');
                        },
                        error: function (data) {
                            toastr.error("Oh! snap...something went wrong!", 'Error!');
                        }
                    });

Now this is straightforward, isnt’it? I thought so too. But when I ran this code, I got the email address correctly in server side, but field “Expertise” was null. Issue was that I was passing the object literal and the request was expecting json.

Every thing started working the moment, I converted “this.expertAreas()” to json using JSON.stringify() (in json2.js). Simple stupid thing, but I lost my 2 hours!!!
(Thanks to my wife for pointing out the error :)

Corrected code is given below, you can stringify the whole object literal too,

                    var request = { };
                   
                    request.Email = this.profileEmail;
                    request.Expertise = JSON.stringify(this.expertAreas());
                   
                    $.ajax({
                        type: "post",
                        url: 'api/usermeta',
                        dataType: 'json',
                        data:request,
                        success: function (data) {
                            toastr.success("Everything is saved, you are all set for now!", 'Wohoo!');
                        },
                        error: function (data) {
                            toastr.error("Oh! snap...something went wrong!", 'Error!');
                        }
                    });

Cheers!