Call Web api method with parameters through Html.UpshotContext

998 Views Asked by At

I am currently working on MVC4 SinglePage Application.

I have a Web Api method GetChartsByCategory(int catId) So in my view cshtml page How shall I declare Html.UpshotContext in this scenario.

I dont want to call GetAllCharts() and then filter on client side using knock out or upshot.

Thanks

2

There are 2 best solutions below

0
On BEST ANSWER

It is not possible to supply parameters, using Html.UpshotContext. You could call GetChartsByCategory() using $.ajax() and mapping the results to your model.

Example:

$.ajax("GetChartsByCategory", true, {
    data: { id: catID },
    dataType: 'json',
    success: function (data) {
        // on success, data contains a list of charts
        self.charts(ko.utils.arrayMap(data, function (item) {
            return new Chart(item);
        }));
    }
});

Model:

Chart = function (initialData) {
    var self = this;

    // inject the initial data
    $.each(initialData, function (key, value) {
        self[key] = ko.observable(value);
    });

....
}
0
On

Another alternative that allows you to stick within the knockout/upshot framework is to alter the upshot provide parameters operation name to include the paramaters as part of the route and/or querystring.

The following example uses an 'ApplicationId' collected from the HTML as the parameter to a WebAPI call to a method that accepts an 'id' parameter as part of the route ('/api/controller/action/id'):

Controller Method:

public class ClientDetailsScreenController : DataController
{
    public ClientModel GetClient(int id)
    {
        var client = //Fetch client with id using your prefered method
        return client;
    }
}

View HTML Upshot Context:

@(Html.UpshotContext(true).DataSource<ClientDetailsScreenController>(ctr => ctr.GetClient(0))))

Note that the '0' passed to the GetClient method gets ignored by the DataSource method so can be anything that will make the method signature valid.

Knockout View Model:

function ClientDetailsViewModel() {
    var self = this;

    //Store the operation name with a leading '/' for use later
    self.operationNameTemplate = upshot.dataSources.Client._providerParameters.operationName + "/";

    //Observable property for the ApplicationId enter via HTML
    self.selectedApplicationId = ko.observable("1");

    //Refresh Data Source Operation - Called in HTML when the ApplicaitonId changes
    self.refresh = function () {
        //Set the upshot operation name to include the id parameter value.
        upshot.dataSources.Client._providerParameters.operationName = self.operationNameTemplate + self.selectedApplicationId();
        //Refresh the data source causing the bound HTMl to be updated.
        self.dataSource = upshot.dataSources.Client.refresh(); 
    };

    //Data Source Setup
    self.refresh();
    self.clients = self.dataSource.getEntities();
}

Hope this helps anyone else who has been trying to get parameters passed to the server via upshot. If anyone has a better way then please let us know.