Taking a fresh look at this this morning, I believe I have a working solution.
Once again, I wanted to remove the intermediary factory abstraction, and have only one abstract data fetching factory that I could pass in parameters directly from from each controller.
$http
is injected into the factory which takes in two parameters whichEntity
, odataUrlBase
, and are set upon instantiation. The factory exposes methods like getList(odataOptions)
. It is these options that are required to to be passed along with the requests as part of the query string, and are done so through $http
's params
.
The new abstract factory is injected into the controller, then instantiated with the required parameters:
app.controller('contentTypeController', ['$scope', '$log', 'abstractFactory3',
function ($scope, $log, abstractFactory3) {
var dataFactory = new abstractFactory3("ContentType", "/odata/ContentType");
Here is the new abstract factory:
app.factory('abstractFactory3', function ($http) {
function abstractFactory3(whichEntity, odataUrlBase) {
this.whichEntity = whichEntity;
this.odataUrlBase = odataUrlBase;
}
abstractFactory3.prototype = {
getList: function (odataOptions) {
//var result = $http({
// url: this.odataUrlBase,
// method: 'GET',
// params: odataParams
//});
return $http.get(this.odataUrlBase, {
params: odataOptions
});
}
};
return abstractFactory3;
});
Since this is being used through through a kendo.data.DataSource
, we have to extract the OData parameters:
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
Upon a successful get
, we pass back the data source's options
with the result:
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read:
function (options) {
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
dataFactory.getList(odataParams)
.success(function (result) {
options.success(result);
});
//$http({ // // example of using $http directly ($http injection was removed from this controller, as this is now handled by the abstract data factory)
// url: crudServiceBaseUrl,
// method: 'GET',
// params: odataParams
//})
//.success(function (result) {
// options.success(result);
//});
}, // update, create, destroy, . . .
I realize that in my original question, the controller was in fact using the Kendo transport, rather than the Angular factory that I had setup.
So what I have now is:
angular controller (KendoUI datasource) -> angular data factory
I have also reworded the question in order to more-accurately reflect what the entire problem was, and hope this is of assistance to someone.
There are some other little nuances, like getting and passing data ID's, objects, JSON.stringification that are best shown in a full solution. Hopefully the following helps:
AngularJS abstract data factory:
app.factory('abstractFactory3', function ($http) {
function abstractFactory3(odataUrlBase) {
this.odataUrlBase = odataUrlBase;
}
abstractFactory3.prototype = {
getList: function (odataOptions) {
//var result = $http({
// url: this.odataUrlBase,
// method: 'GET',
// params: odataParams
//});
return $http.get(this.odataUrlBase, {
params: odataOptions
});
},
get: function (id, odataOptions) {
return $http.get(this.odataUrlBase + '/' + id, {
params: odataOptions
});
},
insert: function (data) {
return $http.post(this.odataUrlBase, data);
},
update: function (id, data) {
return $http.put(this.odataUrlBase + '(' + id + ')', data);
},
remove: function (id) {
return $http.delete(this.odataUrlBase + '(' + id + ')');
}
};
return abstractFactory3;
});
AngularJS Controller:
app.controller('contentTypeController', ['$scope', '$log', 'abstractFactory3',
// the abstract data factory accepts controller type parameters for RESTful CRUD
function ($scope, $log, abstractFactory3) {
var dataFactory = new abstractFactory3("/odata/ContentType");
var crudServiceBaseUrl = "/odata/ContentType";
var dataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read:
function (options) {
var odataParams = kendo.data.transports["odata"].parameterMap(options.data, "read");
dataFactory.getList(odataParams)
.success(function (result) {
options.success(result);
})
.error (function (error) {
console.log("data error");
});
},
update:
function (options) {
var data = options.data;
dataFactory.update(data.ContentTypeId, data)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
},
create:
function (options) {
var data = options.data;
data.ContentTypeId = "0"; // required for valid field data
dataFactory.insert(data)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
},
destroy:
function (options) {
var data = options.data;
dataFactory.remove(data.ContentTypeId)
.success(function (result) {
options.success(result);
})
.error(function (error) {
console.log("data error");
});
},
parameterMap: function (options, type) {
// this is optional - if we need to remove any parameters (due to partial OData support in WebAPI
if (operation !== "read" && options.models) {
return JSON.stringify({ models: options });
}
},
},
batch: false,
pageSize: 10,
serverPaging: true,
change: function (e) {
console.log("change: " + e.action);
// do something with e
},
schema: {
data: function (data) {
//console.log(data)
return data.value;
},
total: function (data) {
console.log("count: " + data["odata.count"]);
return data["odata.count"];
},
model: {
id: "ContentTypeId",
fields: {
ContentTypeId: { editable: false, nullable: true },
//UserId: {editable: false, nullable: false },
Description: { type: "string", validation: { required: true } },
//msrepl_tran_version: { type: "string", validation: { required: true } }
}
}
},
error: function (e) {
//var response = JSON.parse(e.responseText);
var response = e.status;
console.log(response);
}
});
$("#grid").kendoGrid({
dataSource: dataSource,
pageable: true,
height: 400,
toolbar: ["create"],
columns: [
{ field: "ContentTypeId", editable: false, width: 90, title: "ID" },
{ field: "Description", title: "Content Type" },
{ command: ["edit", "destroy"] }
],
editable: "inline"
});
}]);