How to populate Kendo grid with an angular $http GET call - javascript

I'm having trouble binding a Kendo grid to an angular service call. I have an angular $http service that has a getData() method which looks like this:
'use-strict';
payrollApp.factory('dataService', function ($http, $q) {
return {
getData: function () {
var deferred = $q.defer();
$http({
method: 'GET',
url: '/api/apihome/',
}).success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
return deferred.promise;
},
};
});
I then set the grids DataSource in my controller as follows:
'use-strict';
payrollApp.controller('KendoDataGridController', function KendoDataGridController($scope, dataService) {
var companiesList = dataService.getCompanies();
companiesList.then(function(companies) {
console.log(JSON.stringify(companies, undefined, 2));
$scope.companies = new kendo.data.DataSource({
data: companies,
pageSize: 10
});
}, function(status) {
window.alert(status);
console.log(status);
});
}
);
but my grid is not populating. When I set the DataSource's data manually (hard-coded JSON array) it works fine but not when I'm getting the data in my service call, the JSON array being returned by my service is also a valid JSON array (exactly the same as the one I hard coded). Anybody has an idea? I have a feeling this is a promise issue, but even then I'm setting my $scope's companies property when the promise is resolved.
Thanks.

I managed to fix it, there's 2 ways (quite possibly more) of doing this:
1. One is to directly give your kendo grid's datasource the adrress of the Api controller:
$scope.companies = new kendo.data.DataSource({
transport: {
read: {
url: '/api/apihome',
dataType: 'json'
},
},
pageSize: 10
});
There's a full explanation here. But I don't like doing this because I'd rather not hard code API controller addresses in my controller, I prefer to have a service or something return me the data and then pass that on to my grid (Imagine for example wanting to add a token in the $http request headers). So after some messing around I got a way of hooking up the grid with my original approach:
2. We can just hook up the read function of the grid to another function in our service or whatever, which can be any method returning a promise, i.e. a $http call:
dataSource: {
transport: {
read: function (options) {//options holds the grids current page and filter settings
$scope.getCompanies(options.data).then(function (data) {
options.success(data);
$scope.data = data.data;//keep a local copy of the data on the scope if you want
console.log(data);
});
},
parameterMap: function (data, operation) {
return JSON.stringify(data);
}
},
schema: {
data: "data",
total: "total",
},
pageSize: 25,
serverPaging: true,
serverSorting: true
},
EDIT
Regarding how to add items that are already available to the grid, and how to have subsequent requests to the server to get new data, this is how I've gone about doing this:
The grid has an autoBind property, setting that to false prevents the grid automatically calling the server when the view is loaded. So to add items manually I set this to false, and then add rows to the grid via the dataSource.add() method. After that calling dataSource.read() will retrieve more data from the server:
$scope.companiesGridOptions = {
dataSource: new kendo.data.DataSource({
transport: {
read: function (options) {
var config = {
method: "GET",
url: "/api/companies/GetCompanies"
};
$http(config).success(function (data) {
angular.forEach(data, function(d) {
$scope.companiesGridOptions.dataSource.add(d);
});
});
}
},....
Adding items manually to the grid:
$scope.companiesGridOptions.dataSource.data([{id:1,title:"..."}, {id:2,title:"..."}]);
Calling dataSource.read() forces a server call to retrieve data:
$scope.companiesGridOptions.dataSource.read();

I think you should try refreshing your grid once you populate new data:
your_grid.refresh();

Related

Populate select tag with $ngresource promise Angularjs

I have a select on page that i want to populate with data which i get from a server. I'm using service to retrieve this records but how can I access to those values from promise and put them in ng-option of select tag?
Get data from resource:
$scope.categories = Category.all({sorting:"asc"});
Resource:
factory('Category', function ($resource) {
return $resource('api/categories/:id', {}, {
all: {method: "GET", isArray: true, params: {sorting: '#sorting'}},
update: {
method: "PUT",
params: {
id: "#id"
}
}
})
}).
The call to Category.all() should return an array that will be filled with the retrieved values when the respective http request returns. If you want to run some code on completion, you can pass a callback like this:
$scope.categories = Category.all({sorting:"asc"}, function() {
// do something with the $scope.categories
});
You can also obtain a promise like this:
$scope.categories = Category.all({sorting:"asc"})
.$promise.then(function(categories) {
// do something with the categories
});

Get object by id using $resource

I am dealing with a little issue, and need some help.
I have an API setup, works just fine.
Now I want to get a single object using its ID. I have tried using $http, but could't get it to work. So I switched back to $resource. Here is what I have in my service file.
getPlatesInSelectedContainer: function() {
return $resource('/api/v1/platesincontainer/:id', {id: "#id" },{
get: { cache: true, method: 'GET' }
});
},
And in controller I am reaching to function doing so.
CleaningPlatesFactory.getPlatesInSelectedContainer({id : 1}, function(data){
$scope.plates = data;
console.log(data);
})
But this is not returning any results. What I am doing wrong?
UPDATE
Earlier I have tried $http but getting this.
I would still get $http to work. It's as simple as this:
getPlatesInSelectedContainer: function(data) {
return $http.get('/api/v1/platesincontainer/' + data.id);
}
You need to accept the data object in your service function.
Inside the service:
getPlatesInSelectedContainer: function(data) {
return $resource('/api/v1/platesincontainer/:id', {id: data.id },{
get: { cache: true, method: 'GET' }
});
}
Then call it like this:
getPlatesInSelectedContainer({ id: 123 })

Persist additional dataSource.read parameters on paganation in Kendo data grid

I have a Kendo Grid that loads data via ajax with a call to server-side ASP.NET read method:
public virtual JsonResult Read(DataSourceRequest request, string anotherParam)
In my client-side JS, I trigger a read when a button is clicked:
grid.dataSource.read( { anotherParam: 'foo' });
grid.refresh();
This works as expected, only I lose the additional param when I move through the pages of results in the grid, or use the refresh icon on the grid to reload the data.
How do I persist the additional parameter data in the grid?
I have tried setting
grid.dataSource.data
directly, but without much luck. I either get an error if I pass an object, or no effect if I pass the name of a JS function that returns data.
if you want to pass additional parameters to Read ajax datasource method (server side), you may use
.DataSource(dataSource => dataSource
...
.Read(read => read.Action("Read", controllerName, new { anotherParam= "foo"}))
...
)
if you want to pass additional parameters through client scripting you may use datasource.transport.parameterMap, something as below
parameterMap: function(data, type) {
if (type == "read") {
return { request:kendo.stringify(data), anotherParam:"foo" }
}
Use the datasource.transport.parameterMap
parameterMap: function(data, type) {
if (type == "read") {
return kendo.stringify(data, anotherParam);
}
I'm not sure where your other param is coming from, but this is generally how I send extra parameters to the server.
http://docs.telerik.com/kendo-ui/api/javascript/data/datasource#configuration-transport.parameterMap
if use datasource object :
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
data: function () {
return {
additionalParam: value
};
}
},
//parameterMap: function (data, type) {
// and so use this property to send additional param
// return $.extend({ "additionalParam": value }, data);
//}
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
and set options in grid:
$("#grid").kendoGrid({
autoBind: false,
dataSource: dataSource,
selectable: "multiple cell",
allowCopy: true,
columns: [
{ field: "productName" },
{ field: "category" }
]
});
and in click event this code :
dataSource.read();
and in api web method this action:
[HttpGet]
public HttpResponseMessage GetData([FromUri]KendoGridParams/* define class to get parameter from javascript*/ _param)
{
// use _param to filtering, paging and other actions
try
{
var result = Service.AllCustomers();
return Request.CreateResponse(HttpStatusCode.OK, new { result = result });
}
catch (Exception ex)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, new { result = string.Empty });
}
}
good luck.
To persist the updated value of the additional parameter through pagination, you will need to create a global variable and save the value to it.
var anotherParamValue= "";//declare a global variable at the top. Can be assigned some default value as well instead of blank
Then, when you trigger the datasource read event, you should save the value to the global variable we created earlier.
anotherParamValue = 'foo';//save the new value to the global variable
grid.dataSource.read( { anotherParam: anotherParamValue });
grid.refresh();
Now, this is important. In your datasource object transport.read.data must be set to use a function as shown below:
var dataSource = new kendo.data.DataSource({
transport: {
read: {
url: '/Api/GetData',
contentType: "application/json; charset=utf-8", // optional
dataType: "json",
//Must be set to use a function, to pass dynamic values of the parameter
data: function () {
return {
additionalParam: anotherParamValue //get the value from the global variable
};
}
},
},
schema: {
type: "json",
data: function (data) {
return data.result;
},
},
pageSize: 5,
serverPaging: true,
serverSorting: true
});
Now on every page button click, you should get the updated value of the anotherParam which is currently set to foo

How to reset the data after init , Select2

I use Select2-4.0.0 I have been struggling with this problem for a whole day that to update the data.
I search every posts I can like Update select2 data without rebuilding the control, but none have them work.
What I need is really simple (a setter to data):
I have a diaglog, which had a select. Every time I open the diaglog, I will ajax for an data to keep it in a local array like:
when dialog open :
var select2List=syncToLoadTheData();//data for select2
$('#search-user-select').select2({ //here when secondly executed, the select2's data on UI does not refreshed
data:select2List,
matcher: function(params, data){
var key = params.term;
if ($.trim(key) === '') {
return data;
}
if( (matchKeyAndPinyin(key,data.text))){
return data;
}
return null;
}
}
But the problem is even though the list is changing, the select options does not change at all.Please note in my test case, every time i open the dialog, the data from server is changed:
What I had tried:
1.when init:
data: function() { return {results: select2List}; }// not work to show any data at all
2.when secondly open dialog:
$( "#search-user-select").select2('data',newdata,true);//not work to have the new data
3.when secondly open:
$("#search-user-select").select2("updateResults");//Error, does not have this method
And some other method like directly change the array's data(only one copy of the data), but none of them work.
I had the same problem before, my problem was i need to update the select2 after every ajax request with new data.
and this how i fixed my code.
EventId = $(this).attr('id');
$.ajax({
url: 'AjaxGetAllEventPerons',
type: 'POST',
dataType: 'json',
data: {id: EventId},
})
.done(function(data) {
$("#select2_job").select2({
minimumInputLength: 2,
multiple:true,
initSelection : function (element, callback) {
//var data = data;
callback(data);
},
ajax: {
url: "/AjaxGetAllPersonForEvent",
dataType: 'json',
quietMillis: 100,
data: function (term) {
return {
term: term
};
},
results: function (data) {
var myResults = [];
$.each(data, function (index, item) {
myResults.push({
'id': item.id,
'text': item.fullname
});
});
return {
results: myResults
};
}
}
});
I hope this example will help you to solve your problem

JQuery ajax success callback return in another function

I am having one of those ajax asynchronous problems. I have this function which accepts two parameters to send data to the server by jquery ajax. I know this can be done by using promises and callback functions but this is my specific problem.
function fillLightbox(id, text, callback)
{
// get json request of studyunit details
$.ajax(
{
type: 'GET',
url: 'updateExam',
data:
{
get_details: true,
exam_code: text,
event_id: id
},
dataType: 'json',
success: callback
});
}
That is my ajax request, then I have this function for an API:
scheduler.createGridView(
{
name:"grid",
fields:
[
{id:"text", label:'Unit Code', sort:'str', width:200},
{id:"date", label:'Date', sort:'date', width:'*'},
{id:"exam-title", label:'Title', sort:'str', width:'*',
template: function(start, end, ev)
{
fillLightbox(ev.id, ev.text, function(data)
{
var title = data.title;
// i can get my data here..
});
return title; // how can I do this?
}
}
]
});
My question is how can I modify the template function available in this API to be able to return the property. i.e. can I somehow pass a callback function there as well?
Please do not suggest async: false (This obviously works but lags on the browser)
EDIT: more details about Create Grid View template are found here: http://docs.dhtmlx.com/scheduler/grid_view.html#datatemplates
Thanks for your help

Categories