How to load kendo observable data array from MVC controller? - asp.net-mvc

I have the following kendo observable object:
var observable = kendo.observable({
people: [
{ name: "John Doe" },
{ name: "Jane Doe" },
{ name: "Jimmy Doe" }
],
products: [
{ name: "Table" },
{ name: "Chair" },
{ name: "Tomato" }
],
animals: [
{ name: "Dog" },
{ name: "Cat" },
{ name: "Monkey" }
]
});
Can i make the inner collections load Json data directly from seperate controllers?

Yes. You need to create a controller that returns a Json result. Make an ajax call to the controllers route and stuff the response into a variable. Then refer to that in your observable. It might look something like this on the front end:
$.ajax("mysite/getstuff").done(
function(data){
var observable = kendo.observable(data);
});
In this case the getstuff method on the controller needs to return a JSON object containing all of the properties and arrays you need like this:
{
people: [array of people],
products: [array of products],
animals: [array pf animals] //etc
}

Related

Falcor - 'get' no longer emits references as leaf values

I've recently upgraded from Falcor 0.x to 1.1.0 (2.x will be the next step)
According to the Falcor migration documentation, when calling model.get references are not emitted as json anymore.
I'm however wondering what would be the best practice in order to manage references in a model.get.
Here is an example.
Having the following json graph:
{
jsonGraph: {
comment: {
123: {
owner: { $type: "ref", value: ["user", "abc"] },
message: "Foo"
}
},
user: {
abc: {
name: "John Doe"
initials: "JD"
}
}
}
}
Calling model.get will result to:
const json = await model.get(["comment", "123", ["owner", "message"]);
{
owner: undefined, // 0.x was returning `["user", "abc"]`
message: "John Doe"
}
However it's possible to get the owner only:
const json = await model.get(["comment", "123", "owner", ["name", "initials"]);
{
name: "John Doe",
initials: "JD"
}
What is the recommendation for handling references in model.get?
Should I manually get the owner (like the last example?) or should I have an ownerId instead of an owner reference in comment model?
model.get can take any number of pathSets (docs). So, break your first pathSet into two and pass as separate arguments:
await model.get(
["comment", "123", "message"],
["comment", "123", "owner", ["name", "initials"]]
);
which should return
{
message: "John Doe"
owner: {
name: "John Doe",
initials: "JD"
}
}
The underlying constraint is that a single pathSet can only include multiple paths of the same depth. So multiple paths of different depth can only be represented by multiple pathSets.

Falcor - HTTPDataSource to post Json

Is it possible to post a Json file using the falcor.browser's model? I have used the get method in it. Below is what I require, but it is not working.
<script src="./js/falcor.browser.js"></script>
function registerUser() {
var dataSource = new falcor.HttpDataSource("http://localhost/registerUser.json");
var model = new falcor.Model({
source: dataSource
});
var userJson = {"name":"John","age":"35","email":"john#abc.com"};
model.
set(userJson).
then(function(done){
console.log(done);
});
This is the server.js code:
app.use('/registerUser.json', falcorExpress.dataSourceRoute(function (req, res) {
return new Router([
{
route: "rating",
get: function() {
// Post call to external Api goes here
}
}
]);
}));
A few things:
The Model's set() method takes 1+ pathValues, so reformat your userJson object literal into a set of pathValues. Something like:
model.
set(
{ path: ['users', 'id1', 'name'], value: 'John' },
{ path: ['users', 'id1', 'age'], value: 35 },
{ path: ['users', 'id1', 'email'], value: 'john#abc.com' }
).
then(function(done){
console.log(done);
});
Second, your router must implement set handlers to correspond to the paths you are trying to set. These handlers should also return pathValues:
new Router([
{
route: 'users[{keys:ids}]["name", "age", "email"]',
set: function(jsonGraph) {
// jsonGraph looks like { users: { id1: { name: "John", age: 35, email: "john#abc.com" }
// make request to update name/age/email fields and return updated pathValues, e.g.
return [
{ path: ['users', 'id1', 'name'], value: 'John' },
{ path: ['users', 'id1', 'age'], value: 35 },
{ path: ['users', 'id1', 'email'], value: 'john#abc.com' },
];
}
}
]);
Given that your DB request is likely asynchronous, your route get handler will have to return a promise or observable. But the above should work as a demonstration.
Edit
You can also use route pattern matching on the third path key if the number of fields gets large, as was demonstrated above on the second id key.
{
route: 'users[{keys:ids}][{keys:fields}]',
set: function(jsonGraph) {
/* jsonGraph looks like
{
users: {
id1: { field1: "xxx", field2: "yyy", ... },
id1: { field1: "xxx", field2: "yyy", ... },
...
}
}
*/
}
}

Access nested JSON property in jspdf autotable plugin

I have just started using jsPDF and the AutoTable plugin, and it is almost perfect for what we are using it for. One question...
Is it possible to assign a dataKey in the columns definition to a nested property within the JSON that is being mapped to the table?
We have a JSON structure that looks like this:
"Primary_Key": "12345",
"Site_Name": {
"Address_Name": "Address 1"
},
"Default_Screen_Name": "Bob",
"Full_Name": "Bob Smith"
If we use the following columns:
var columns = [
{ title: "ID", dataKey: "Primary_Key" },
{ title: "Screen Name", dataKey: "Default_Screen_Name" },
{ title: "Full Name", dataKey: "Full_Name" }];
Everything works perfectly. However, we would also like to do something like the following:
var columns = [
{ title: "ID", dataKey: "Primary_Key" },
{ title: "Iterations", dataKey: "Iterations" },
{ title: "Screen Name", dataKey: "Default_Screen_Name" },
{ title: "Site Name", dataKey: "Site_Name.Address_Name" }];
Where we are using Site_Name.Address_Name to index into the nested JSON object to retrieve the value.
Is something like this possible?
Not at the moment. You can follow that feature request here. Your options are currently to either flatten the data before passing it to autotable or use the hooks to extract the specific text you want. That can be done like this:
var columns = [
{title: "ID", dataKey: "id"},
{title: "Name", dataKey: "name"},
{title: "Country", dataKey: "address"}
];
var rows = [
{id: 1, name: "Shaw", address: {country: "Tanzania"}},
{id: 2, name: "Nelson", address: {country: "Kazakhstan"}},
{id: 3, name: "Garcia", address: {country: "Madagascar"}}
];
var doc = jsPDF();
doc.autoTable(columns, rows, {
didParseCell: function(data) {
if (data.column.dataKey === 'address') {
data.cell.text = data.cell.raw.country;
}
}
});
doc.save('table.pdf');
<script src="https://unpkg.com/jspdf#1.3.3/dist/jspdf.min.js"></script>
<script src="https://unpkg.com/jspdf-autotable#2.3.1/dist/jspdf.plugin.autotable.js"></script>
Update for additional question in comments:
var columns = [
{title: "Country", dataKey: "address", displayProperty: "country"},
...
];
var rows = [...];
...
didParseCell: function(data) {
if (data.column.dataKey === 'address') {
var prop = data.column.raw.displayProperty;
data.cell.text = data.cell.raw[prop];
}
}

KendoUI datasource: parseInt of filter value

I need to filter a Kendo datasource through the following filter item object:
filters: [
{
field: "FIELD",
operator: "lt",
value: "080"
}
]
That means, because of the way data are transmitted, I am trying to test a case like: "013" < "080".
But it does not work out of the box.
Is there a way to define a filter with something like a "parseInt" on the tested values?
Thank you!
Try defining FIELD as a number in model:
schema : {
model: {
fields: {
FIELD : { type: "number" }
}
}
},
If you do so, then FIELD is displayed as 13, 80,... If you want to display FIELD with leading 0, use the following in the column definition of the grid.
{ field: "FIELD", title: "Field", format: "{0:000}" }
Doing this FIELD is considered as a number even that it is displayed as 013, 080...
You should have something like:
var dataSource = new kendo.data.DataSource({
data : entries,
batch : true,
schema : {
model: {
fields: {
FIELD: { type: "number" }
}
}
}
});
var grid = $("#grid").kendoGrid({
dataSource: dataSource,
columns : [
{ field: "FIELD", title: "Field", format: "{0:000}" }
],
filterable: true
}).data("kendoGrid");
If you want to try it, see it in JSFiddle here
EDIT: Updated code for using format instead of template as Mateo Piazza suggested

How do I return unnamed JSON string array from asp.net mvc2 json result?

I have the following code:
var json = MyObject
.Select(p => new
{
id = p.MyObjectId,
name = p.MyObjectName
});
return Json(new { json }, JsonRequestBehavior.AllowGet);
This returns a JSON object as follows:
{ json: [ { id: 1, name: "Bob" }, { id: 2, name: "Fred" }, { id: 3, name: "James" } ] }
However, I need it to return the data as:
[ { id: 1, name: "Bob" }, { id: 2, name: "Fred" }, { id: 3, name: "James" } ]
Is this possible using the JSON result?
return Json(json, JsonRequestBehavior.AllowGet);
Try this:
return Json(json, JsonRequestBehavior.AllowGet);

Resources