breeze: client-side model with navigationProperty is giving error - breeze

When calling addEntityType for ResourceUnavailabilities, I get the error: error configuring an instance of 'NavigationProperty'. The 'entityTypeName' parameter must be a 'string'
I don't get it. I've looked at the tutorial on breeze's website, and I can't tell what I'm doing wrong.
client-side model:
metadataStore.addEntityType({
shortName: 'Unavailability',
namespace: 'ecdt',
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
startDate: { dataType: DT.DateTimeOffset },
endDate: { dataType: DT.DateTimeOffset },
isDayOff: { dataType: DT.Boolean }
}
});
metadataStore.registerEntityTypeCtor('Unavailability', null, null);
metadataStore.addEntityType({
shortName: 'ResourceUnavailabilities',
namespace: 'ecdt',
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
resourceId: { dataType: DT.Int32 },
},
navigationProperties: {
unavailabilities: { dataType: 'Unavailability', hasMany: true }
}
});
metadataStore.registerEntityTypeCtor('ResourceUnavailabilities', null, null);
Apart from that everthing works fine. I can create Unavailability entities and also ResourceUnavailabilities entities (as long as I remove the navigation property...)
Also, in the tutorial, you use the nameproperty instead of shortname. If I do that, I get an error
Error configuring an instance of 'EntityType'. Unknown property: 'name'. Is the sample out-of-date ?

Ok, it's solved. The correct mapping is:
metadataStore.addEntityType({
shortName: 'Unavailability',
namespace: 'ecdt',
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
startDate: { dataType: DT.DateTimeOffset },
endDate: { dataType: DT.DateTimeOffset },
isDayOff: { dataType: DT.Boolean }
},
navigationProperties: {
unavailabilities: { entityTypeName: 'ResourceUnavailabilities', isScalar: true, associationName: "test" }
}
});
metadataStore.registerEntityTypeCtor('Unavailability', null, null);
metadataStore.addEntityType({
shortName: 'ResourceUnavailabilities',
namespace: 'ecdt',
dataProperties: {
id: { dataType: DT.Guid, isPartOfKey: true },
resourceId: { dataType: DT.Int32 },
},
navigationProperties: {
unavailabilities: { entityTypeName: 'Unavailability', isScalar: false, associationName: "test" }
}
});
Looks like the breeze document is not exactly up-to-date.

Related

Data is getting but not populating in kendo grid using angular js

I am able to get the data from database but not populating in gridview.
here is my code below:
<div ng-app="app" ng-controller="MyCtrl">
<div kendo-grid k-options="gridOptions" k-rebind="gridOptions" k-pageable='{ "pageSize": 2, "refresh": true, "pageSizes": true }'></div>
</div>
<script>
angular.module("app", ["kendo.directives"]).controller("MyCtrl", function ($scope, $http) {
$scope.gridOptions = {
columns: [{ field: "EmployeeKey" }, { field: "FirstName" }],
dataSource: {
//schema: {
// data: "d"
//},
type: "jsonp",
transport: {
read: function (e) {
$http({ method: 'GET', url: '/Employee/Employee_Read' }).
success(function (data, status, headers, config) {
// alert('Sucess')
//debugger;
e.success(data)
}).
error(function (data, status, headers, config) {
alert('something went wrong')
console.log(status);
});
}
},
//pageSize: 5
}
}
});
</script>
and this is the controller page where i am getting data
public ActionResult Employee_Read ([DataSourceRequest] DataSourceRequest request )
{
//IQueryable<IEmployeeRepositary> employeeRep = employeeRepositary.Employees;
return Json(employeeRepositary.Employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
so after running my application i am checking through debugger this line
"e.success(data)" so in mouse hove i am getting the total records fetched from database. but not populating in gridview it is still showing blank.
please help me out from here.
Because you are returning collection which wrapped with DataSourceResult method.
return Json(employeeRepositary.Employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
instead of just its collection
return Json(employeeRepositary.Employees, JsonRequestBehavior.AllowGet);
You need to define your data source schema, please try this schema setup
schema: {
data: "Data",
errors: "Errors",
total: "Total",
model: {
id: "Id",
fields: {
Id: { editable: false, defaultValue: 0 },
//the rest field definition
}
}
}
and you can change your transport's read to something like this
read: {
type: "POST",
url: "/Employee/Employee_Read",
dataType: "json",
contentType: "application/json"
}
your final code should be like this
$scope.gridOptions = {
columns: [{ field: "EmployeeKey" }, { field: "FirstName" }],
dataSource: {
transport: {
read: {
type: "POST",
url: "/Employee/Employee_Read",
dataType: "json",
contentType: "application/json"
},
parameterMap: function(options, operation) {
return JSON.stringify(options);
}
},
pageSize: 5,
schema: {
data: "Data",
errors: "Errors",
total: "Total",
model: {
id: "EmployeeKey",
fields: {
EmployeeKey: { editable: false, defaultValue: 0 },
FirstName: {type: "string", validation: { required: true }}
}
}
}
}
}
and your controller like this
[AcceptVerbs(HttpVerbs.Get | HttpVerbs.Post)]
public ActionResult Employee_Read ([DataSourceRequest] DataSourceRequest request )
{
var employees = employeeRepositary.Employees;
return Json(employees.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}

Grid Not populating in kendoGrid

I am using MVC 4 and kendo UI for grid population. But the grid is not populating correctly.
this is my View :
<script type="text/javascript">
$.ajax({
url: '#Url.Action("Employee_Read", "UserSummary")',
type: 'GET',
dataType: "json",
Async: true,
success: function (data, textStatus, xhr) {
var dataloc = data;
var element = $("#grid4").kendoGrid({
dataSource: {
data: dataloc,
schema: {
model: {
fields: {
userDetailsId: { type: "number", editable: false },
name: { type: "string", editable: false },
roleId: { type: "string", editable: false },
emailId: { type: "string", editable: false }
}
}
}
}
});
}
});
</script>
Conroller ;
[HttpGet]
public ActionResult Employee_Read([DataSourceRequest]DataSourceRequest request)
{
using (var emp = new MockProjectAkarshEntities1())
{
IQueryable<tbl_UserDetails> userDetails = emp.tbl_UserDetails;
DataSourceResult result = userDetails.ToDataSourceResult(request);
return Json(result,JsonRequestBehavior.AllowGet);
}
In the output I am getting something like "[object][object]" and no of rows in the table returned from database.the skeleton of grid is coming but not the data. I am new to MVC and kendo. Please help me out.
The data you received should be started with {"Data": So simply change your code from var dataloc = data; to var dataloc = data.Data; just confirm it by visiting UserSummary/Employee_Read.
You can also set the dataSource later on like this (if you prefer at some stage)
<script type="text/javascript">
$.ajax({
url: '#Url.Action("Employee_Read", "UserSummary")',
type: 'GET',
dataType: "json",
Async: true,
success: function (data, textStatus, xhr) {
var dataloc = data.Data;
var element = $("#grid4").kendoGrid({
dataSource: {
// data: dataloc,
schema: {
model: {
fields: {
userDetailsId: { type: "number", editable: false },
name: { type: "string", editable: false },
roleId: { type: "string", editable: false },
emailId: { type: "string", editable: false }
}
}
}
}
});
// create data source using the data received
var ds = new kendo.data.DataSource({
data: dataloc
});
$('#grid4').data('kendoGrid').setDataSource(ds);
}
});
</script>

How to configure a non-embedded hasMany relationship with breeze.js

I'm trying to configure a few models with breeze.js
The first is session and I was able to get this working perfectly with a simple query like the below
var query = breeze.EntityQuery.from("sessions").toType("Session");
..but when I tried to add a related "speakers" array to the session I seem to be left with an empty array after the materialization step is complete
Do I need to write a custom json adapter for an api that looks like this?
/api/sessions/
[
{
"id": 1,
"name": "javascript",
"speakers": [
1
]
}
]
/api/speakers/1/
{
"id": 1,
"name": "Toran",
"session": 1
}
Here is my current model configuration (mostly working)
var ds = new breeze.DataService({
serviceName: 'api',
hasServerMetadata: false,
useJsonp: false
});
breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
this.instance = new breeze.EntityManager({dataService: ds});
this.instance.metadataStore.addEntityType({
shortName: "Speaker",
namespace: "App",
dataProperties: {
id: { dataType: "Int64", isPartOfKey: true },
name: { dataType: "String" },
session: { dataType: "Int64" }
},
navigationProperties: {
session: {
entityTypeName: "Session", isScalar: true,
associationName: "session", foreignKeyNames: ["session"]
}
}
});
this.instance.metadataStore.addEntityType({
shortName: "Session",
namespace: "App",
dataProperties: {
id: { dataType: "Int64", isPartOfKey: true },
name: { dataType: "String" },
speakers: { dataType: "Undefined" }
},
navigationProperties: {
speakers: {
entityTypeName: "Speaker", isScalar: false,
associationName: "speakers", foreignKeyNames: ["speakers"]
}
}
});
Thanks for the help !
note** I'm using ember.js (not backbone/ko/angular)
I tried to keep the above brief but if you need absolutely everything, checkout this single js file
https://github.com/toranb/embereeze/blob/master/website/static/website/js/app.js
update
if I remove the "speakers" dataProperty breeze gets fairly unhappy in this block of code (as it's not a dataProperty on the session model)
var fkProps = fkNames.map(function (fkName) {
//fkName is speakers .... yet it's not a data property so bad things happen :(
return parentEntityType.getDataProperty(fkName);
});
var fkPropCollection = parentEntityType.foreignKeyProperties;
// Array.prototype.push.apply(parentEntityType.foreignKeyProperties, fkProps);
fkProps.forEach(function (dp) {
I just did a PR - the association name should be the same on both ends, much like any relational database would have.
this.instance.metadataStore.addEntityType({
shortName: "Speaker",
namespace: "App",
dataProperties: {
id: { dataType: "Int64", isPartOfKey: true },
name: { dataType: "String" },
session: { dataType: "Int64" }
},
navigationProperties: {
sessionModel: {
entityTypeName: "Session", isScalar: true,
associationName: "Speaker_Sessions", foreignKeyNames: ["session"]
}
}
});
this.instance.metadataStore.addEntityType({
shortName: "Session",
namespace: "App",
dataProperties: {
id: { dataType: "Int64", isPartOfKey: true },
name: { dataType: "String" }
},
navigationProperties: {
speakers: {
entityTypeName: "Speaker", isScalar: false,
associationName: "Speaker_Sessions"
}
}
});
So I renamed the association, removed the extra speakers property on the Session (there is no property for the relationship, simply an inverse that should be mapped) and then removed the foreign key on the session as you don't need one there. By assigning passing session down from the API with the models shown above should be enough to let Breeze know
Speakers' have a session property, which is a foreign key pointing to a single session.
Sessions have a collection of speakers, which should be mapped on the other end

JQWidgets jqxGrid: Dataadapter and Paging

i have a newbie question, but i’m scratching my head on this one. I have a grid, bound to a dataadapter. On the grid, paging and filtering is explicit disabled, but the GET-call from the dataadapter allways includes following parameters in the GET-url:
?filterscount=0&groupscount=0&pagenum=0&pagesize=10&recordstartindex=0&recordendindex=18&_=1386768031615
I want to get all data, then cache it clientside for paging and filtering, but in the first step i just want to get my data bound to the grid.
Here’s my code:
var source = {
type: "GET",
datatype: "json",
datafields: [
{ name: 'url' },
{ name: 'category', type: 'int' },
{ name: 'info' },
{ name: 'status', type: 'bool' }
],
url: '/api/redirects/Getallredirects',
id: 'id'
};
var dataAdapter = new $.jqx.dataAdapter(source, {
contentType: 'application/json; charset=utf-8',
loadError: function (xhr, status, error) {
alert(error);
},
downloadComplete: function (data) {
var returnData = {};
returnData.records = data.d;
return returnData;
}
});
$("#jqxgrid").jqxGrid({
source: dataAdapter,
filterable: false,
pageable: false,
virtualmode: false,
columns: [
{ text: 'URL', dataField: 'url', width: 100 },
{ text: 'Category', dataField: 'category', width: 100 },
{ text: 'Info', dataField: 'info', width: 180 },
{ text: 'Status', dataField: 'status', width: 80, cellsalign: 'right' },
]
});
I don’t get any data, the GET-call fails because of the automatically included parameters. How do i get rid of these parameters?
I just found in the jqxGrid documentation a reference to these parameters, but no example, how to remove them:
http://www.jqwidgets.com/jquery-widgets-documentation/documentation/jqxgrid/jquery-grid-extra-http-variables.htm
Thanks in advance for any help.
The below will remove the default parameters:
var dataAdapter = new $.jqx.dataAdapter(source,
{
formatData: function (data) {
return {};
}
}
);

extjs 4.2 load store grid when open window

i'am new with extjs. i have an application asp.net mvc with integrated extjs 4.2 mvc. My application will have multi windows. now i one menu with button and onclick event button open the windows. have two windows. each windows there is a grid with different store, but when i open the windows, extjs load wrong store. i don't understand. the store is setting autoload:false. but don't work =(.
store UtenteStore.js:
Ext.define('MyApp.store.UtenteStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.utenteData'
],
constructor: function (cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
autoSave: false,
model: 'MyApp.model.utenteData',
storeId: 'MyJsonStore',
idProperty: 'Id',
proxy: proxy
}, cfg)]);
}
});
var writer = new Ext.data.JsonWriter({
type: 'json',
writeAllFields: true,
allowSingle: false
});
var reader = new Ext.data.JsonReader({
totalProperty: 'total',
type: 'json',
successProperty: 'success',
messageProperty: 'message'
});
var proxy = new Ext.data.HttpProxy({
timeout: 120000,
noCache: false,
reader:reader,
writer: writer,
type: 'ajax',
api: {
read: '/Clienti/Get',
create: '/Clienti/Update',
update: '/Clienti/Update',
destroy: '/Clienti/Delete'
},
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
});
store FornitoreStore.js:
Ext.define('MyApp.store.FornitoriStore', {
extend: 'Ext.data.Store',
requires: [
'MyApp.model.fornitoriData'
],
constructor: function (cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
autoSave: false,
model: 'MyApp.model.fornitoriData',
storeId: 'MyJsonStore2',
idProperty: 'Id',
proxy: proxy
}, cfg)]);
}
});
var writer = new Ext.data.JsonWriter({
type: 'json',
writeAllFields: true,
allowSingle: false
});
var reader = new Ext.data.JsonReader({
totalProperty: 'total',
type: 'json',
successProperty: 'success',
messageProperty: 'message'
});
var proxy = new Ext.data.HttpProxy({
timeout: 120000,
noCache: false,
reader: reader,
writer: writer,
type: 'ajax',
api: {
read: '/Fornitori/Lista',
create: '',
update: '',
destroy: ''
},
headers: {
'Content-Type': 'application/json; charset=UTF-8'
}
});
this is my first windows Clienti.js:
var editor = Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
});
Ext.define('MyApp.view.clienti.Clienti', {
extend: 'Ext.window.Window',
height:600,
width: 800,
shadow: 'drop',
collapsible: true,
title: 'Lista Clienti',
maximizable: true,
initComponent: function() {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'gridpanel',
id: 'gridpanelId',
header:false,
store:'MyApp.store.UtenteStore',
forceFit: true,
columnLines: true,
autoResizeColumns: true,
selType: 'rowmodel',
columns: [
{
dataIndex: 'CodiceCliente',
text: 'Codice',
filter: {
type: 'int',
minValue: 1
}
},
{
xtype: 'gridcolumn',
dataIndex: 'DescrizioneCliente',
text: 'Descrizione',
editor: {
xtype: 'textfield',
allowBlank: true
},
filter: true
},
{
xtype: 'datecolumn',
dataIndex: 'date',
text: 'Date'
},
{
xtype: 'booleancolumn',
dataIndex: 'bool',
text: 'Boolean'
}
],
listeners: {
afterrender: {
fn: me.loadDb,
scope: me
}
},
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
items: [
{
xtype: 'button',
text: 'Inserisci',
listeners: {
click: {
fn: me.inserisciClick,
scope: me
}
}
},
{
xtype: 'button',
text: 'Elimina',
listeners: {
click: {
fn: me.eliminaClick,
scope: me
}
}
},
{
xtype: 'button',
text: 'Salva',
listeners: {
click: {
fn: me.salvaClick,
scope: me
}
}
}
]
}
],
plugins: [editor, {
ptype: 'filterbar',
renderHidden: false,
showShowHideButton: true,
showClearAllButton: true
}]
}
]
});
me.callParent(arguments);
},
loadDb: function (component, eOpts) {
},
inserisciClick: function (button, e, eOpts) {
editor.cancelEdit();
Ext.getCmp('gridpanelId').getStore().insert(0, "");
editor.startEdit(0, 0);
},
eliminaClick: function (button, e, eOpts) {
var sm = Ext.getCmp('gridpanelId').getSelectionModel();
Ext.getCmp('gridpanelId').getStore().remove(sm.getSelection());
},
salvaClick: function(button, e, eOpts) {
Ext.getCmp('gridpanelId').getStore().sync();
}
});
this is my second windows ListaFornitori.js:
Ext.define('MyApp.view.fornitori.ListaFornitori', {
extend: 'Ext.window.Window',
height: 600,
width: 900,
layout: {
type: 'absolute'
},
title: 'Lista Fornitori',
initComponent: function () {
var me = this;
Ext.applyIf(me, {
items: [
{
xtype: 'tabpanel',
activeTab: 0,
items: [
{
xtype: 'panel',
title: 'Lista',
items: [
{
xtype: 'gridpanel',
id: 'grdListaFornitori',
height: 362,
header: false,
store:'MyApp.store.FornitoriStore',
forceFit: true,
columnLines: true,
autoResizeColumns: true,
title: '',
columns: [
{
xtype: 'gridcolumn',
dataIndex: 'CodiceFornitore',
text: 'Codice',
filter: {
type: 'int',
minValue: 1
}
},
{
xtype: 'gridcolumn',
dataIndex: 'DescrizioneFornitore',
text: 'Descrizione',
filter:true
}
],
plugins: [{
ptype: 'filterbar',
renderHidden: false,
showShowHideButton: true,
showClearAllButton: true
}],
viewConfig: {
preserveScrollOnRefresh: true,
listeners: {
afterrender: {
fn: me.loadDb,
scope: me
},
celldblclick: {
fn: me.editClick,
scope: me
}
}
}
}
]
}
]
},
{
xtype: 'button',
x: 750,
y: 450,
text: 'Inserisci',
icon: '/Scripts/ext-4.2/resources/ico/add.png',
listeners: {
click: {
fn: me.inserisciClick,
scope: me
}
}
}
]
});
me.callParent(arguments);
},
loadDb: function (component, eOpts) {
},
editClick: function (tableview, td, cellIndex, record, tr, rowIndex, e, eOpts) {
Ext.create('MyApp.view.fornitori.InsFornitori', { rIx: rowIndex }).show();
},
inserisciClick: function(button, e, eOpts) {
Ext.create('MyApp.view.fornitori.InsFornitori').show();
}
});
Infine this is my app.js:
Ext.Loader.setConfig({
enabled: true,
disableCaching: true,
paths : {
'MyApp' : '../MyApp'
}
});
Ext.application({
models: [
'utenteData',
'fornitoriData'
],
stores: [
'MyApp.store.UtenteStore',
'MyApp.store.FornitoriStore'
],
views: [
'clienti.Clienti',
'MyViewport',
'fornitori.InsFornitori',
'fornitori.ListaFornitori',
'fornitori.Fornitori'
],
autoCreateViewport: true,
name: 'MyApp',
appFolder: '../MyApp',
});
and this my strucut:
could someone help me? It is some days that I'm stuck?
sorry for my english
There are two ways:
Option 1: This is tested.
xtype: 'gridpanel',
id: 'grdListaFornitori',
... ...
listeners: {
render:{
scope: this,
fn: function(grid) {
//load store after the grid is done rendering
grid.getStore().load();
}
}
}
Option 2: Didn't try this option yet. But It should work.
loadDb: function (component, eOpts) {
component.ownerCt.getStore().load();
},
I am a newbie using extj too, and I can look that you never call the load() method in your stores. You had set autoLoad property to false. Try to call it, and make me know that it works. Good Luck!

Resources