SlideShare une entreprise Scribd logo
1  sur  83
Handle real world data
with confidence.
Fredric Berling
@FredricBerling
fredric@entence.se
• Reading & saving simple data
When we live in a perfect world. Domain model is perfect. We decide everything.
• Real world data and demands
Still simple data but add real world scenarios and demands. Learn how to configure to cope with it.
• Associations
How to handle associate data.
• Multi model scenarios
Learn about Ext.data.Session to track changes in multiple models and associations.
• Errors
2
Agenda
Reading simple data
Model View ViewModel ViewController
Sencha MVVM recap
Model View ViewModel ViewController
Sencha MVVM recap
Ext.data.Model Ext.Component Ext.app.ViewModel Ext.app.ViewControlle
r
Model View ViewModel ViewController
Sencha MVVM recap
Ext.data.Model Ext.Component Ext.app.ViewModel Ext.app.ViewControlle
r
View Package
CRM.view.Viewport CRM.view.ViewportModel CRM.view.ViewportController
Our sample application
View Package
resources/getCompanyById.json
• Id field is lowercase
• Date is formatted in a understandable
format
{
id : 100,
companyName : 'Ikea',
address : 'Storgatan 1',
city : 'Stockholm',
country : 'Sweden',
updatedDate : '1973-11-17 05:30'
}
The data model
• Fields config are not really needed for
simple data types.
.. except date
• Simple proxy config
Ext.define('CRM.model.CompanyProfile', {
extend: 'Ext.data.Model',
fields:[
{
name : 'updatedDate',
type : 'date’
}
],
proxy: {
url : 'resources/getCompanyById.json'
}
});
Data loading
• linkTo function
Creates a link to a record by loading data
from configured proxy and setting it on the
view model with a simple name.
"companyProfile" will be our reference in
all bindings referring to company data
record.
Ext.define('CRM.view.ViewportController', {
extend : 'Ext.app.ViewController',
alias : 'controller.viewportcontroller',
init: function() {
this.getViewModel().linkTo('companyProfile',{
type : 'CRM.model.CompanyProfile',
id : 100
});
}
});
Ext.define('CRM.view.Viewport', {
extend : 'Ext.Container',
viewModel : 'viewportmodel',
controller : 'viewportcontroller',
padding : 20,
items: [
{
xtype : 'textfield',
fieldLabel : 'Company name',
bind : '{companyProfile.companyName}'
},
{
xtype : 'textfield',
fieldLabel : 'Address',
bind : '{companyProfile.address}'
}
...
]
});
Bind fields to view
Ext.define('CRM.view.Viewport', {
extend : 'Ext.Container',
viewModel : 'viewportmodel',
controller : 'viewportcontroller',
padding : 20,
items: [
'''
]
});
• viewModel
- connects this view to the viewmodel with
alias "viewportmodel"
• controller
- connects this view to the viewController
with alias "viewportcontroller"
View configs
Live demo
Simple read
Saving simple data
Save button
Ext.define('CRM.view.ViewportController', {
extend : 'Ext.app.ViewController',
alias : 'controller.viewportcontroller',
onSave:function(){
this.getViewModel().get('companyProfile').save();
}
});
Ext.define('CRM.view.Viewport', {
extend : 'Ext.Panel',
viewModel : 'viewportmodel',
controller : 'viewportcontroller',
padding : 20,
buttons:[
{
text:'Save',
handler:'onSave'
}
],
items: [
{
xtype : 'textfield',
fieldLabel : 'Company name',
bind : '{companyProfile.companyName}'
}
...
Save function
Live demo
Simple
Read/Save
HTTP Post
{
"id": 100,
"companyName": "Ikea AB",
"address": "Storgatan 1",
"city": "Malmö",
"country": "Sweden",
"updatedDate": "2016-08-23 19:47"
}
{
id:100,
companyName:"Ikea AB"
}
Required response
Noteworthy
• Only dirty field data was sent.
• Id was always sent
• Same URL as read
• Response data was automatically realized in view
19
Real world data and demands
Real world data from Customer
• Observations
- id field is not "id"
{
_id : "57bb5d639baeb676ced2b0de",
companyName : 'Ikea',
address : {
street : 'Storgatan 1',
city : 'Stockholm',
country : 'Sweden'
},
updatedDate : '2016-08-23T21:26:08.358Z'
}
Real world data from Customer
• Observations
- id field is not "id"
- Some data resides is in objects
{
_id : "57bb5d639baeb676ced2b0de",
companyName : 'Ikea',
address : {
street : 'Storgatan 1',
city : 'Stockholm',
country : 'Sweden'
},
updatedDate : '2016-08-23T21:26:08.358Z'
}
Real world data from Customer
• Observations
- id field is not "id"
- Some data resides is in objects
- Date format
{
_id : "57bb5d639baeb676ced2b0de",
companyName : 'Ikea',
address : {
street : 'Storgatan 1',
city : 'Stockholm',
country : 'Sweden'
},
updatedDate : '2016-08-23T21:26:08.358Z'
}
Scenarios/Customer demands
• Id must be "_id". We are using Mongo DB.
• Updated date should ignore timezones
• The exact same JSON structure must be sent on save.
• Always send all data on save.
• Save must be on separate url.
24
Specify your own id field
idProperty
Consider doing this in abstract base
class or even override Ext.data.Model.
Ext.define('CRM.model.CompanyProfile', {
extend: 'Ext.data.Model',
idProperty:'_id',
fields:[
{
name: 'updatedDate',
type : 'date’
}
],
proxy: {
url : 'resources/getCompanyById.json'
}
});
Read data from nested objects
mapping
Specify a dot notated path in the fields
array of data model.
fields:[
{
name : 'street',
mapping : 'address.street',
type : 'string'
},
{
name : 'city',
mapping : 'address.city',
type : 'string'
},
{
name : 'country',
mapping : 'address.country',
type : 'string'
},
...
],
Send all fields on save
writeAllFields
Proxy writer configs to ensure all fields
will be sent.
proxy: {
type : 'ajax',
url : '/companies',
reader:{
type:'json'
},
writer:{
type : 'json',
writeAllFields : true
}
}
Keep object nesting on save
{
_id : "57bb5d639baeb676ced2b0de",
companyName : 'Ikea',
address : {
street : 'Storgatan 1',
city : 'Stockholm',
country: 'Sweden'
},
updatedDate : '2016-08-23T21:26:08.358Z'
}
Keep object nesting on save
expandData
Makes sure the mapped field data sent
back is in a nested format.
nameProperty
Property used to read the key for each
value that will be sent to the server.
proxy: {
type : 'ajax',
url : '/companies',
reader:{
type:'json'
},
writer:{
type : 'json',
writeAllFields : true,
nameProperty : 'mapping',
expandData : true
}
}
Live demo
Real world data
Date should not add timezone
By default you will get a localized date
in the current browsers timezone
{
_id : "57bb5d639baeb676ced2b0de",
companyName : 'Ikea',
address : {
street : 'Storgatan 1',
city : 'Stockholm',
country: 'Sweden'
},
updatedDate : '2016-08-23T21:26:08.358Z'
}
dateFormat
Adding the exact date format will make
sure date is not altered.
fields:[
'''
{
name:'updatedDate',
type:'date',
dateFormat:'Y-m-dTH:i:s.uZ'
}
],
Read/Update on separate Url´s
Instead of using the proxy standard url
config, we change to the more versatile
api config
proxy: {
type : 'ajax',
url : '/companies'
reader:{
type:'json'
},
writer:{
type : 'json',
nameProperty : 'mapping',
writeAllFields : true,
expandData : true
}
}
Read/Update on separate Url´s
Instead of using the proxy standard url
config, we change to the more versatile
api config
proxy: {
type : 'ajax',
api : {
read: '/companies',
update: '/updateCompanies'
},
reader:{
type:'json'
},
writer:{
type : 'json',
nameProperty : 'mapping',
writeAllFields : true,
expandData : true
}
}
Associations
Associated licenses
{
"_id": "57bf32fe9baeb676ced2b0e1",
"companyName": "Ikea",
"address": {
"street": "Storgatan 3",
"city": "Malmö",
"country": "Sweden"
},
"updatedDate": "2016-08-25T18:51:39.671Z",
"licenses": [
{
"id": 1,
"product": "ExtJS 2.1",
"amount": 5
},
{
"id": 2,
"product": "ExtJS 4.1",
"amount": 5
},
.......
]
License references Company
Ext.define('CRM.model.License', {
extend: 'Ext.data.Model',
idgen:'uuid',
idProperty:'_id',
fields:[
{name:'product', type:'string'},
{name:'amount', type:'float'},
{
name: 'companyId',
reference: {
parent : 'CRM.model.CompanyProfile',
inverse : {
role : 'licenses'
}
}
}
Company
License
License
License
License references Company
Ext.define('CRM.model.License', {
extend: 'Ext.data.Model',
idgen:'uuid',
idProperty:'_id',
fields:[
{name:'product', type:'string'},
{name:'amount', type:'float'},
{
name: 'companyId',
reference: {
parent : 'CRM.model.CompanyProfile',
inverse : {
role : 'licenses'
}
}
}
Company
License
License
License
License references Company
Ext.define('CRM.model.License', {
extend: 'Ext.data.Model',
idgen:'uuid',
idProperty:'_id',
fields:[
{name:'product', type:'string'},
{name:'amount', type:'float'},
{
name: 'companyId',
reference: {
parent : 'CRM.model.CompanyProfile',
inverse : {
role : 'licenses'
}
}
}
Company
License
License
License
Useful?
• Automatically created stores.
Company model function licenses() will return
accociated licenses.
var viewModel = this.getViewModel(),
companyProfile = viewModel.get('companyProfile'),
store = companyProfile.licenses();
Useful?
• Automatically created stores.
Company model function licenses() will return
accociated licenses.
• License function getCompany() will
return Company model.
varviewModel = this.getViewModel(),
companyProfile = viewModel.get('licenses'),
store = companyProfile.licenses(),
firstLicense = store.first(),
console.log(firstCompany.getCompany());
// Returns companyProfile
Useful?
• Automatically created stores.
Company model function licenses() will return
accociated licenses.
• License function getCompany() will
return Company model.
• Nice bindings.
companyProfile.licenses references
the store
{
xtype : 'grid',
plugins : 'cellediting',
columnLines:true,
bind : {
store:'{companyProfile.licenses}'
},
columns:[
{text: 'Licence', dataIndex:'product'},
{text: 'Amount', dataIndex:'amount'}
]
}
• Inline associations
Licence data is array in company JSON and should be saved in same call as company profile.
• Proxy/Remote associations
Licence data is fetched from its own web service and CRUD operations are handled here
43
Possible business scenarios
Inline associations
{
"_id": "57bf32fe9baeb676ced2b0e1",
"companyName": "Ikea",
"address": {
"street": "Storgatan 3",
"city": "Malmö",
"country": "Sweden"
},
"updatedDate": "2016-08-25T18:51:39.671Z",
"licenses": [
{
"id": 1,
"product": "ExtJS 2.1",
"amount": 5
},
{
"id": 2,
"product": "ExtJS 4.1",
"amount": 5
},
.......
]
GET
Inline associations
{
"_id": "57bf32fe9baeb676ced2b0e1",
"companyName": "Ikea",
"address": {
"street": "Storgatan 3",
"city": "Malmö",
"country": "Sweden"
},
"updatedDate": "2016-08-25T18:51:39.671Z",
"licenses": [
{
"id": 1,
"product": "ExtJS 2.1",
"amount": 5
},
{
"id": 2,
"product": "ExtJS 4.1",
"amount": 5
},
.......
]
POST
allDataOptions
Proxy writer needs to be told to save
associated data.
.
proxy: {
type : 'ajax',
api : {
read: '/companies',
update: '/updateCompanies'
},
writer:{
type : 'json',
nameProperty : 'mapping',
writeAllFields : true,
expandData : true,
allDataOptions :{
associated:true
}
}
}
Company model
Associated store data is not realized on save.
Live example
47
Saving associated data in a big JSON is generally a bad idea
The associated data is probably saved in a table in a database
Empty arrays will have to force delete
48
3 Possible solutions
• Re-load all data after successful
save
- extra call
- safe
onSave:function(){
this.getViewModel().get('companyProfile').save({
callback:function(){
this.getViewModel().linkTo('companyProfile',{
type : 'CRM.model.CompanyProfile',
id : '57bf32fe9baeb676ced2b0e1'
});
},
scope:this
});
}
3 Possible solutions
• Re-load all data after successful
save
- extra call
- safe
• Forced commitChanges()
- no extra call
- response data is ignored.
onSave:function(){
var store = this.getViewModel().get('companyProfile.licenses')
this.getViewModel().get('companyProfile').save({
callback:function(){
store.commitChanges(); },
},
scope:this
});
}
3 Possible solutions
• Re-load all data after successful
save
- extra call
- safe
• Forced commitChanges()
- no extra call
- response data is ignored.
• Code around it
- complex
What happens if license array is missing?
Demo!
52
Associated stores will default to a ajax
proxy.
Avoid remote reads by changing this to
a memory proxy.
Ext.define('CRM.model.License', {
extend: 'Ext.data.Model',
fields:[
{name:'product', type:'string'},
{name:'amount', type:'float'},
{
name: 'companyId',
reference: {
parent : 'CRM.model.CompanyProfile',
inverse : {
role:'licenses',
storeConfig:{
proxy:{
type:'memory'
}
}
}
}
. . .
Store config
Proxy/Remote associations
Ext.define('CRM.view.ViewportController', {
extend : 'Ext.app.ViewController',
alias : 'controller.viewportcontroller',
onSave:function(){
var vm = this.getViewModel();
vm.get('companyProfile').save();
vm.get('companyProfile.licenses').sync();
},
...
• Call save() on model.
• Call sync() on stores.
Proxy/Remote associations
Ext.define('CRM.model.License', {
extend: 'Ext.data.Model',
idProperty:'_id',
fields:[..],
proxy: {
type : 'ajax',
api : {
read : '/licenses',
create : '/addLicenses',
update : '/updateLicenses',
destroy : '/deleteLicenses'
},
writer:{
type : 'json',
writeAllFields : true
}
}
});
• Specify all api´s on associated data
model
Proxy/Remote associations
{
xtype: 'grid',
plugins: 'cellediting',
columnLines: true,
tbar: [{text: 'Add', handler: 'addLicense'}],
bind: {
store: '{companyProfile.licenses}'
}
},
• Associated data will only load if store
is used in a binding
Proxy/Remote associations
filter:[
{
"property":"companyId",
"value":"57bcbaa29baeb676ced2b0e0",
"exactMatch":true
}
]
• On read, a filter will be posted.
- property is the reference name,
- value is the reference Id
Backend must honor this filter and return
the correct subset.
• Live Example
HTTP GET /licenses
Multi models scenarios
59
Ext.data.Session
The primary job of a Session is to manage a collection of records of many different
types and their associations. This often starts by loading records when requested
and culminates when it is time to save to the
60
View with multiple models
61
Company
Licenses
Pool cars
Feedback
View with multiple models
62
Company
Licenses
Pool cars
Feedback
Data model + association
View with multiple models
63
Company
Licenses
Pool cars
Feedback
Data model + association
Store
View with multiple models
64
Company
Licenses
Pool cars
Feedback
Data model + association
Store
Data model
• getChanges()
- Returns an object describing all of the modified fields, created or dropped records
maintained by this session.
- Used to track if ANY data is dirty
• getSaveBatch()
- Returns an Ext.data.Batch containing the Ext.data.operation.Operation instances that
are needed to save all of the changes in this session
65
Session features
One point save onSave:function(){
if(this.getSession().getChanges()){
this.getSession().getSaveBatch().start();
}
},
Enable session Ext.define('CRM.view.Viewport', {
extend : 'Ext.Panel',
viewModel : 'viewportmodel',
controller : 'viewportcontroller',
bodyPadding : 20,
session:true,
buttons:[
{
text:'Save',
handler:'onSave'
}
],
layout:{
type:'vbox',
align:'stretch'
},
. . . .
• Enable session in view
Enable session var store = this.getViewModel().getStore('cars');
store.setSession(this.getSession());
• Enable session in view
• Add stores to session
Enable session CRM.model.Feedback.load('57d072659baeb676ced2b0e5',{
success:function(record){
this.getViewModel().set('feedback', record);
},
scope:this
}, this.getSession());
• Enable session in view
• Add stores to session
• Provide session in model load
Enable session this.getViewModel().linkTo('companyProfile',{
type : 'CRM.model.CompanyProfile',
id : '57bcbaa29baeb676ced2b0e0'
});• Enable session in view
• Add stores to session
• Provide session in model load
• Use LinkTo
- uses session from viewModel
Live demo
Multi Model
Sending extra parameters
Extra proxy parameters proxy: {
type : 'ajax',
extraParams:{
appName:'CRM'
},
api : {
read: '/companies',
update: '/updateCompanies'
},
reader:{
type:'json'
},
writer:{
type : 'json',
}
}
• Set in proxy using extraParams
config
Extra proxy parameters var proxy = Ext.ClassManager.get(<class>).getProxy();
proxy.setExtraParam('appName', 'CRM');
• Set in proxy using extraParams
config
• Set from controller using the
setExtraParam function
Operation parameters vm.get('companyProfile').save({
params:{
appHeight:this.getView().getHeight();
}
});
vm.get('companyProfile.licenses').sync({
params:{
appHeight:this.getView().getHeight();
}
});
• Send params config into operational
methods,
Live demo
Extra Parameters
Errors with messages
Handle error response {
"IsSuccess": false,
"ErrorMessage": "Missing company"
}Error returned from the server in a json
response when logic fails or data is
missing.
Configure the proxy reader proxy: {
type : 'ajax',
api : {
read: '/companies',
update: '/updateCompanies'
},
reader:{
type:'json',
successProperty:'IsSuccess',
messageProperty:'ErrorMessage'
}
. . .
• successProperty
The property indicating that the operation
was successful or not.
• messageProperty
The property where the error message is
returned.
Listen for proxy exception Ext.mixin.Observable.observe(Ext.data.proxy.Server);
Ext.data.proxy.Server.on('exception',
function(proxy, resp, operation){
Ext.Msg.alert('Error', operation.getError());
}
);
• exception
- fires when "success" is false
- fires on HTTP exceptions
• operation.getError()
- returns messageProperty content
Live demo
Error handling
Please Take the Survey in the Mobile App
• Navigate to this session in the mobile app
• Click on “Evaluate Session”
• Respondents will be entered into a drawing to win one of five $50 Amazon gift cards
Handle real world data with confidence

Contenu connexe

Tendances

Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoMohamed Mosaad
 
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceParashuram N
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEARMarkus Wolff
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical MementoOdoo
 
Databinding and Performance-Tuning in Angular 2
Databinding and Performance-Tuning in Angular 2Databinding and Performance-Tuning in Angular 2
Databinding and Performance-Tuning in Angular 2Manfred Steyer
 
Build a better UI component library with Styled System
Build a better UI component library with Styled SystemBuild a better UI component library with Styled System
Build a better UI component library with Styled SystemHsin-Hao Tang
 
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB
 
Kief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleKief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleThoughtworks
 
What's new in iOS 7
What's new in iOS 7What's new in iOS 7
What's new in iOS 7barcelonaio
 
GQL cheat sheet latest
GQL cheat sheet latestGQL cheat sheet latest
GQL cheat sheet latestsones GmbH
 
GQL CheatSheet 1.1
GQL CheatSheet 1.1GQL CheatSheet 1.1
GQL CheatSheet 1.1sones GmbH
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 

Tendances (20)

Dig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup CairoDig Deeper into WordPress - WD Meetup Cairo
Dig Deeper into WordPress - WD Meetup Cairo
 
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
MongoDB .local Munich 2019: Aggregation Pipeline Power++: How MongoDB 4.2 Pip...
 
IndexedDB - Querying and Performance
IndexedDB - Querying and PerformanceIndexedDB - Querying and Performance
IndexedDB - Querying and Performance
 
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local London 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
JavaScript JQUERY AJAX
JavaScript JQUERY AJAXJavaScript JQUERY AJAX
JavaScript JQUERY AJAX
 
Autopsy Of A Widget
Autopsy Of A WidgetAutopsy Of A Widget
Autopsy Of A Widget
 
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDBMongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
MongoDB .local Munich 2019: Tips and Tricks++ for Querying and Indexing MongoDB
 
Rapid Prototyping with PEAR
Rapid Prototyping with PEARRapid Prototyping with PEAR
Rapid Prototyping with PEAR
 
Drupal 8: Fields reborn
Drupal 8: Fields rebornDrupal 8: Fields reborn
Drupal 8: Fields reborn
 
OpenERP Technical Memento
OpenERP Technical MementoOpenERP Technical Memento
OpenERP Technical Memento
 
Databinding and Performance-Tuning in Angular 2
Databinding and Performance-Tuning in Angular 2Databinding and Performance-Tuning in Angular 2
Databinding and Performance-Tuning in Angular 2
 
MongoDB With Style
MongoDB With StyleMongoDB With Style
MongoDB With Style
 
Build a better UI component library with Styled System
Build a better UI component library with Styled SystemBuild a better UI component library with Styled System
Build a better UI component library with Styled System
 
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDBMongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
MongoDB .local Paris 2020: La puissance du Pipeline d'Agrégation de MongoDB
 
03DOM.ppt
03DOM.ppt03DOM.ppt
03DOM.ppt
 
Kief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terribleKief Morris - Infrastructure is terrible
Kief Morris - Infrastructure is terrible
 
What's new in iOS 7
What's new in iOS 7What's new in iOS 7
What's new in iOS 7
 
GQL cheat sheet latest
GQL cheat sheet latestGQL cheat sheet latest
GQL cheat sheet latest
 
GQL CheatSheet 1.1
GQL CheatSheet 1.1GQL CheatSheet 1.1
GQL CheatSheet 1.1
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 

En vedette

SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...Sencha
 
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...Sencha
 
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...Sencha
 
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...Sencha
 
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...Sencha
 
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSencha
 
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySencha
 
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...Sencha
 
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...Sencha
 
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSencha
 
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...Sencha
 
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay PlatonovSenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay PlatonovSencha
 
Ext JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsExt JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsSencha
 
Building Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoBuilding Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoSencha
 
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...Sencha
 
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...Sencha
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSencha
 
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi   SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi Sencha
 
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...Sencha
 
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...Sencha
 

En vedette (20)

SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
SenchaCon 2016: How to Give your Sencha App Real-time Web Performance - James...
 
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
SenchaCon 2016: LinkRest - Modern RESTful API Framework for Ext JS Apps - Rou...
 
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
SenchaCon 2016: Creating a Flexible and Usable Industry Specific Solution - D...
 
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
SenchaCon 2016: Refine Enterprise Applications by Focusing on U0ser Experienc...
 
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
SenchaCon 2016: Turbocharge your Ext JS App - Per Minborg, Anselm McClain, Jo...
 
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil ManvarSenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
SenchaCon 2016: Developing and Delivering Quality Code, Frequently - Neil Manvar
 
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory HardySenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
SenchaCon 2016: JavaScript is Great but Stop Writing It - Rory Hardy
 
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
SenchaCon 2016: Mobile First? Desktop First? Or Should you Think Universal Ap...
 
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
SenchaCon 2016: Integrating Geospatial Maps & Big Data Using CartoDB via Ext ...
 
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
 
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
SenchaCon 2016: How to Auto Generate a Back-end in Minutes - Per Minborg, Emi...
 
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay PlatonovSenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
SenchaCon 2016: Handling Undo-Redo in Sencha Applications - Nickolay Platonov
 
Ext JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell SimeonsExt JS Architecture Best Practices - Mitchell Simeons
Ext JS Architecture Best Practices - Mitchell Simeons
 
Building Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff StanoBuilding Ext JS Using HATEOAS - Jeff Stano
Building Ext JS Using HATEOAS - Jeff Stano
 
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
SenchaCon 2016: Upgrading an Ext JS 4.x Application to Ext JS 6.x - Mark Linc...
 
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
SenchaCon 2016: Accessibility, Teamwork & Ext JS: A Customer Success Story - ...
 
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don GriffinSenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
SenchaCon 2016: Modernizing the Ext JS Class System - Don Griffin
 
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi   SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
SenchaCon 2016: The Modern Toolchain - Ross Gerbasi
 
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
SenchaCon 2016: Using Ext JS 6 for Cross-Platform Development on Mobile - And...
 
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
SenchaCon 2016: Building a Faceted Catalog of Video Game Assets Using Ext JS ...
 

Similaire à Handle real world data with confidence

How We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFHow We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFSeanGraham5
 
Evolving your Data Access with MongoDB Stitch - Drew Di Palma
Evolving your Data Access with MongoDB Stitch - Drew Di PalmaEvolving your Data Access with MongoDB Stitch - Drew Di Palma
Evolving your Data Access with MongoDB Stitch - Drew Di PalmaMongoDB
 
Dynamic_UI_Concepts_version_2.pdf
Dynamic_UI_Concepts_version_2.pdfDynamic_UI_Concepts_version_2.pdf
Dynamic_UI_Concepts_version_2.pdfJoeRodriguez477329
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWAREFIWARE
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Sparkhound Inc.
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB
 
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB StitchMongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB StitchMongoDB
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WAREFermin Galan
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casellentuck
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and SymfonyIgnacio Martín
 
Building Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchBuilding Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchMongoDB
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databindingBoulos Dib
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsAdégòkè Obasá
 
Applying Code Customizations to Magento 2
Applying Code Customizations to Magento 2 Applying Code Customizations to Magento 2
Applying Code Customizations to Magento 2 Igor Miniailo
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IVisual Engineering
 
How to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR RestHow to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR Restshravan kumar chelika
 
Introduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinIntroduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinSimon Gauvin
 

Similaire à Handle real world data with confidence (20)

Knockout.js
Knockout.jsKnockout.js
Knockout.js
 
How We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADFHow We Brought Advanced HTML5 Viewing to ADF
How We Brought Advanced HTML5 Viewing to ADF
 
Evolving your Data Access with MongoDB Stitch - Drew Di Palma
Evolving your Data Access with MongoDB Stitch - Drew Di PalmaEvolving your Data Access with MongoDB Stitch - Drew Di Palma
Evolving your Data Access with MongoDB Stitch - Drew Di Palma
 
Dynamic_UI_Concepts_version_2.pdf
Dynamic_UI_Concepts_version_2.pdfDynamic_UI_Concepts_version_2.pdf
Dynamic_UI_Concepts_version_2.pdf
 
Developing your first application using FIWARE
Developing your first application using FIWAREDeveloping your first application using FIWARE
Developing your first application using FIWARE
 
MongodB Internals
MongodB InternalsMongodB Internals
MongodB Internals
 
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
Optimizing Code Reusability for SharePoint using Linq to SharePoint & the MVP...
 
MongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDBMongoDB.local Atlanta: Introduction to Serverless MongoDB
MongoDB.local Atlanta: Introduction to Serverless MongoDB
 
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB StitchMongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
MongoDB.local Sydney: Evolving your Data Access with MongoDB Stitch
 
Developing your first application using FI-WARE
Developing your first application using FI-WAREDeveloping your first application using FI-WARE
Developing your first application using FI-WARE
 
Jasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-casJasigsakai12 columbia-customizes-cas
Jasigsakai12 columbia-customizes-cas
 
Server side rendering with React and Symfony
Server side rendering with React and SymfonyServer side rendering with React and Symfony
Server side rendering with React and Symfony
 
Building Your First App with MongoDB Stitch
Building Your First App with MongoDB StitchBuilding Your First App with MongoDB Stitch
Building Your First App with MongoDB Stitch
 
Knockoutjs databinding
Knockoutjs databindingKnockoutjs databinding
Knockoutjs databinding
 
IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web Apps
 
Applying Code Customizations to Magento 2
Applying Code Customizations to Magento 2 Applying Code Customizations to Magento 2
Applying Code Customizations to Magento 2
 
Workshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte IWorkshop 12: AngularJS Parte I
Workshop 12: AngularJS Parte I
 
How to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR RestHow to convert custom plsql to web services-Soap OR Rest
How to convert custom plsql to web services-Soap OR Rest
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
 
Introduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinIntroduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon Gauvin
 

Plus de Sencha

Breathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsBreathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsSencha
 
Ext JS 6.6 Highlights
Ext JS 6.6 HighlightsExt JS 6.6 Highlights
Ext JS 6.6 HighlightsSencha
 
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha
 
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha
 
Sencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha
 
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha
 
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha
 
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha
 
Sencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha
 
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha
 
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridLeveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridSencha
 
Learn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportLearn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportSencha
 
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsIntroducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsSencha
 

Plus de Sencha (14)

Breathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web ComponentsBreathe New Life into Your Existing JavaScript Applications with Web Components
Breathe New Life into Your Existing JavaScript Applications with Web Components
 
Ext JS 6.6 Highlights
Ext JS 6.6 HighlightsExt JS 6.6 Highlights
Ext JS 6.6 Highlights
 
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
Sencha Roadshow 2017: BufferedStore Internals featuring eyeworkers interactiv...
 
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
Sencha Roadshow 2017: Build Progressive Web Apps with Ext JS and Cmd
 
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App TestingSencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
Sencha Roadshow 2017: Best Practices for Implementing Continuous Web App Testing
 
Sencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha TestSencha Roadshow 2017: What's New in Sencha Test
Sencha Roadshow 2017: What's New in Sencha Test
 
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
Sencha Roadshow 2017: Sencha Upgrades - The Good. The Bad. The Ugly - Eva Luc...
 
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and ToolingSencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
Sencha Roadshow 2017: Modernizing the Ext JS Class System and Tooling
 
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
Sencha Roadshow 2017: Sencha Best Practices: Coworkee App
 
Sencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop FirstSencha Roadshow 2017: Mobile First or Desktop First
Sencha Roadshow 2017: Mobile First or Desktop First
 
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and BeyondSencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
Sencha Roadshow 2017: Innovations in Ext JS 6.5 and Beyond
 
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data GridLeveraging React and GraphQL to Create a Performant, Scalable Data Grid
Leveraging React and GraphQL to Create a Performant, Scalable Data Grid
 
Learn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research ReportLearn Key Insights from The State of Web Application Testing Research Report
Learn Key Insights from The State of Web Application Testing Research Report
 
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React AppsIntroducing ExtReact: Adding Powerful Sencha Components to React Apps
Introducing ExtReact: Adding Powerful Sencha Components to React Apps
 

Dernier

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 

Dernier (20)

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 

Handle real world data with confidence

  • 1. Handle real world data with confidence. Fredric Berling @FredricBerling fredric@entence.se
  • 2. • Reading & saving simple data When we live in a perfect world. Domain model is perfect. We decide everything. • Real world data and demands Still simple data but add real world scenarios and demands. Learn how to configure to cope with it. • Associations How to handle associate data. • Multi model scenarios Learn about Ext.data.Session to track changes in multiple models and associations. • Errors 2 Agenda
  • 4. Model View ViewModel ViewController Sencha MVVM recap
  • 5. Model View ViewModel ViewController Sencha MVVM recap Ext.data.Model Ext.Component Ext.app.ViewModel Ext.app.ViewControlle r
  • 6. Model View ViewModel ViewController Sencha MVVM recap Ext.data.Model Ext.Component Ext.app.ViewModel Ext.app.ViewControlle r View Package
  • 8.
  • 9. resources/getCompanyById.json • Id field is lowercase • Date is formatted in a understandable format { id : 100, companyName : 'Ikea', address : 'Storgatan 1', city : 'Stockholm', country : 'Sweden', updatedDate : '1973-11-17 05:30' }
  • 10. The data model • Fields config are not really needed for simple data types. .. except date • Simple proxy config Ext.define('CRM.model.CompanyProfile', { extend: 'Ext.data.Model', fields:[ { name : 'updatedDate', type : 'date’ } ], proxy: { url : 'resources/getCompanyById.json' } });
  • 11. Data loading • linkTo function Creates a link to a record by loading data from configured proxy and setting it on the view model with a simple name. "companyProfile" will be our reference in all bindings referring to company data record. Ext.define('CRM.view.ViewportController', { extend : 'Ext.app.ViewController', alias : 'controller.viewportcontroller', init: function() { this.getViewModel().linkTo('companyProfile',{ type : 'CRM.model.CompanyProfile', id : 100 }); } });
  • 12. Ext.define('CRM.view.Viewport', { extend : 'Ext.Container', viewModel : 'viewportmodel', controller : 'viewportcontroller', padding : 20, items: [ { xtype : 'textfield', fieldLabel : 'Company name', bind : '{companyProfile.companyName}' }, { xtype : 'textfield', fieldLabel : 'Address', bind : '{companyProfile.address}' } ... ] }); Bind fields to view
  • 13. Ext.define('CRM.view.Viewport', { extend : 'Ext.Container', viewModel : 'viewportmodel', controller : 'viewportcontroller', padding : 20, items: [ ''' ] }); • viewModel - connects this view to the viewmodel with alias "viewportmodel" • controller - connects this view to the viewController with alias "viewportcontroller" View configs
  • 16. Save button Ext.define('CRM.view.ViewportController', { extend : 'Ext.app.ViewController', alias : 'controller.viewportcontroller', onSave:function(){ this.getViewModel().get('companyProfile').save(); } }); Ext.define('CRM.view.Viewport', { extend : 'Ext.Panel', viewModel : 'viewportmodel', controller : 'viewportcontroller', padding : 20, buttons:[ { text:'Save', handler:'onSave' } ], items: [ { xtype : 'textfield', fieldLabel : 'Company name', bind : '{companyProfile.companyName}' } ... Save function
  • 18. HTTP Post { "id": 100, "companyName": "Ikea AB", "address": "Storgatan 1", "city": "Malmö", "country": "Sweden", "updatedDate": "2016-08-23 19:47" } { id:100, companyName:"Ikea AB" } Required response
  • 19. Noteworthy • Only dirty field data was sent. • Id was always sent • Same URL as read • Response data was automatically realized in view 19
  • 20. Real world data and demands
  • 21. Real world data from Customer • Observations - id field is not "id" { _id : "57bb5d639baeb676ced2b0de", companyName : 'Ikea', address : { street : 'Storgatan 1', city : 'Stockholm', country : 'Sweden' }, updatedDate : '2016-08-23T21:26:08.358Z' }
  • 22. Real world data from Customer • Observations - id field is not "id" - Some data resides is in objects { _id : "57bb5d639baeb676ced2b0de", companyName : 'Ikea', address : { street : 'Storgatan 1', city : 'Stockholm', country : 'Sweden' }, updatedDate : '2016-08-23T21:26:08.358Z' }
  • 23. Real world data from Customer • Observations - id field is not "id" - Some data resides is in objects - Date format { _id : "57bb5d639baeb676ced2b0de", companyName : 'Ikea', address : { street : 'Storgatan 1', city : 'Stockholm', country : 'Sweden' }, updatedDate : '2016-08-23T21:26:08.358Z' }
  • 24. Scenarios/Customer demands • Id must be "_id". We are using Mongo DB. • Updated date should ignore timezones • The exact same JSON structure must be sent on save. • Always send all data on save. • Save must be on separate url. 24
  • 25. Specify your own id field idProperty Consider doing this in abstract base class or even override Ext.data.Model. Ext.define('CRM.model.CompanyProfile', { extend: 'Ext.data.Model', idProperty:'_id', fields:[ { name: 'updatedDate', type : 'date’ } ], proxy: { url : 'resources/getCompanyById.json' } });
  • 26. Read data from nested objects mapping Specify a dot notated path in the fields array of data model. fields:[ { name : 'street', mapping : 'address.street', type : 'string' }, { name : 'city', mapping : 'address.city', type : 'string' }, { name : 'country', mapping : 'address.country', type : 'string' }, ... ],
  • 27. Send all fields on save writeAllFields Proxy writer configs to ensure all fields will be sent. proxy: { type : 'ajax', url : '/companies', reader:{ type:'json' }, writer:{ type : 'json', writeAllFields : true } }
  • 28. Keep object nesting on save { _id : "57bb5d639baeb676ced2b0de", companyName : 'Ikea', address : { street : 'Storgatan 1', city : 'Stockholm', country: 'Sweden' }, updatedDate : '2016-08-23T21:26:08.358Z' }
  • 29. Keep object nesting on save expandData Makes sure the mapped field data sent back is in a nested format. nameProperty Property used to read the key for each value that will be sent to the server. proxy: { type : 'ajax', url : '/companies', reader:{ type:'json' }, writer:{ type : 'json', writeAllFields : true, nameProperty : 'mapping', expandData : true } }
  • 31. Date should not add timezone By default you will get a localized date in the current browsers timezone { _id : "57bb5d639baeb676ced2b0de", companyName : 'Ikea', address : { street : 'Storgatan 1', city : 'Stockholm', country: 'Sweden' }, updatedDate : '2016-08-23T21:26:08.358Z' }
  • 32. dateFormat Adding the exact date format will make sure date is not altered. fields:[ ''' { name:'updatedDate', type:'date', dateFormat:'Y-m-dTH:i:s.uZ' } ],
  • 33. Read/Update on separate Url´s Instead of using the proxy standard url config, we change to the more versatile api config proxy: { type : 'ajax', url : '/companies' reader:{ type:'json' }, writer:{ type : 'json', nameProperty : 'mapping', writeAllFields : true, expandData : true } }
  • 34. Read/Update on separate Url´s Instead of using the proxy standard url config, we change to the more versatile api config proxy: { type : 'ajax', api : { read: '/companies', update: '/updateCompanies' }, reader:{ type:'json' }, writer:{ type : 'json', nameProperty : 'mapping', writeAllFields : true, expandData : true } }
  • 36. Associated licenses { "_id": "57bf32fe9baeb676ced2b0e1", "companyName": "Ikea", "address": { "street": "Storgatan 3", "city": "Malmö", "country": "Sweden" }, "updatedDate": "2016-08-25T18:51:39.671Z", "licenses": [ { "id": 1, "product": "ExtJS 2.1", "amount": 5 }, { "id": 2, "product": "ExtJS 4.1", "amount": 5 }, ....... ]
  • 37. License references Company Ext.define('CRM.model.License', { extend: 'Ext.data.Model', idgen:'uuid', idProperty:'_id', fields:[ {name:'product', type:'string'}, {name:'amount', type:'float'}, { name: 'companyId', reference: { parent : 'CRM.model.CompanyProfile', inverse : { role : 'licenses' } } } Company License License License
  • 38. License references Company Ext.define('CRM.model.License', { extend: 'Ext.data.Model', idgen:'uuid', idProperty:'_id', fields:[ {name:'product', type:'string'}, {name:'amount', type:'float'}, { name: 'companyId', reference: { parent : 'CRM.model.CompanyProfile', inverse : { role : 'licenses' } } } Company License License License
  • 39. License references Company Ext.define('CRM.model.License', { extend: 'Ext.data.Model', idgen:'uuid', idProperty:'_id', fields:[ {name:'product', type:'string'}, {name:'amount', type:'float'}, { name: 'companyId', reference: { parent : 'CRM.model.CompanyProfile', inverse : { role : 'licenses' } } } Company License License License
  • 40. Useful? • Automatically created stores. Company model function licenses() will return accociated licenses. var viewModel = this.getViewModel(), companyProfile = viewModel.get('companyProfile'), store = companyProfile.licenses();
  • 41. Useful? • Automatically created stores. Company model function licenses() will return accociated licenses. • License function getCompany() will return Company model. varviewModel = this.getViewModel(), companyProfile = viewModel.get('licenses'), store = companyProfile.licenses(), firstLicense = store.first(), console.log(firstCompany.getCompany()); // Returns companyProfile
  • 42. Useful? • Automatically created stores. Company model function licenses() will return accociated licenses. • License function getCompany() will return Company model. • Nice bindings. companyProfile.licenses references the store { xtype : 'grid', plugins : 'cellediting', columnLines:true, bind : { store:'{companyProfile.licenses}' }, columns:[ {text: 'Licence', dataIndex:'product'}, {text: 'Amount', dataIndex:'amount'} ] }
  • 43. • Inline associations Licence data is array in company JSON and should be saved in same call as company profile. • Proxy/Remote associations Licence data is fetched from its own web service and CRUD operations are handled here 43 Possible business scenarios
  • 44. Inline associations { "_id": "57bf32fe9baeb676ced2b0e1", "companyName": "Ikea", "address": { "street": "Storgatan 3", "city": "Malmö", "country": "Sweden" }, "updatedDate": "2016-08-25T18:51:39.671Z", "licenses": [ { "id": 1, "product": "ExtJS 2.1", "amount": 5 }, { "id": 2, "product": "ExtJS 4.1", "amount": 5 }, ....... ] GET
  • 45. Inline associations { "_id": "57bf32fe9baeb676ced2b0e1", "companyName": "Ikea", "address": { "street": "Storgatan 3", "city": "Malmö", "country": "Sweden" }, "updatedDate": "2016-08-25T18:51:39.671Z", "licenses": [ { "id": 1, "product": "ExtJS 2.1", "amount": 5 }, { "id": 2, "product": "ExtJS 4.1", "amount": 5 }, ....... ] POST
  • 46. allDataOptions Proxy writer needs to be told to save associated data. . proxy: { type : 'ajax', api : { read: '/companies', update: '/updateCompanies' }, writer:{ type : 'json', nameProperty : 'mapping', writeAllFields : true, expandData : true, allDataOptions :{ associated:true } } } Company model
  • 47. Associated store data is not realized on save. Live example 47
  • 48. Saving associated data in a big JSON is generally a bad idea The associated data is probably saved in a table in a database Empty arrays will have to force delete 48
  • 49. 3 Possible solutions • Re-load all data after successful save - extra call - safe onSave:function(){ this.getViewModel().get('companyProfile').save({ callback:function(){ this.getViewModel().linkTo('companyProfile',{ type : 'CRM.model.CompanyProfile', id : '57bf32fe9baeb676ced2b0e1' }); }, scope:this }); }
  • 50. 3 Possible solutions • Re-load all data after successful save - extra call - safe • Forced commitChanges() - no extra call - response data is ignored. onSave:function(){ var store = this.getViewModel().get('companyProfile.licenses') this.getViewModel().get('companyProfile').save({ callback:function(){ store.commitChanges(); }, }, scope:this }); }
  • 51. 3 Possible solutions • Re-load all data after successful save - extra call - safe • Forced commitChanges() - no extra call - response data is ignored. • Code around it - complex
  • 52. What happens if license array is missing? Demo! 52
  • 53. Associated stores will default to a ajax proxy. Avoid remote reads by changing this to a memory proxy. Ext.define('CRM.model.License', { extend: 'Ext.data.Model', fields:[ {name:'product', type:'string'}, {name:'amount', type:'float'}, { name: 'companyId', reference: { parent : 'CRM.model.CompanyProfile', inverse : { role:'licenses', storeConfig:{ proxy:{ type:'memory' } } } } . . . Store config
  • 54. Proxy/Remote associations Ext.define('CRM.view.ViewportController', { extend : 'Ext.app.ViewController', alias : 'controller.viewportcontroller', onSave:function(){ var vm = this.getViewModel(); vm.get('companyProfile').save(); vm.get('companyProfile.licenses').sync(); }, ... • Call save() on model. • Call sync() on stores.
  • 55. Proxy/Remote associations Ext.define('CRM.model.License', { extend: 'Ext.data.Model', idProperty:'_id', fields:[..], proxy: { type : 'ajax', api : { read : '/licenses', create : '/addLicenses', update : '/updateLicenses', destroy : '/deleteLicenses' }, writer:{ type : 'json', writeAllFields : true } } }); • Specify all api´s on associated data model
  • 56. Proxy/Remote associations { xtype: 'grid', plugins: 'cellediting', columnLines: true, tbar: [{text: 'Add', handler: 'addLicense'}], bind: { store: '{companyProfile.licenses}' } }, • Associated data will only load if store is used in a binding
  • 57. Proxy/Remote associations filter:[ { "property":"companyId", "value":"57bcbaa29baeb676ced2b0e0", "exactMatch":true } ] • On read, a filter will be posted. - property is the reference name, - value is the reference Id Backend must honor this filter and return the correct subset. • Live Example HTTP GET /licenses
  • 59. 59
  • 60. Ext.data.Session The primary job of a Session is to manage a collection of records of many different types and their associations. This often starts by loading records when requested and culminates when it is time to save to the 60
  • 61. View with multiple models 61 Company Licenses Pool cars Feedback
  • 62. View with multiple models 62 Company Licenses Pool cars Feedback Data model + association
  • 63. View with multiple models 63 Company Licenses Pool cars Feedback Data model + association Store
  • 64. View with multiple models 64 Company Licenses Pool cars Feedback Data model + association Store Data model
  • 65. • getChanges() - Returns an object describing all of the modified fields, created or dropped records maintained by this session. - Used to track if ANY data is dirty • getSaveBatch() - Returns an Ext.data.Batch containing the Ext.data.operation.Operation instances that are needed to save all of the changes in this session 65 Session features
  • 66. One point save onSave:function(){ if(this.getSession().getChanges()){ this.getSession().getSaveBatch().start(); } },
  • 67. Enable session Ext.define('CRM.view.Viewport', { extend : 'Ext.Panel', viewModel : 'viewportmodel', controller : 'viewportcontroller', bodyPadding : 20, session:true, buttons:[ { text:'Save', handler:'onSave' } ], layout:{ type:'vbox', align:'stretch' }, . . . . • Enable session in view
  • 68. Enable session var store = this.getViewModel().getStore('cars'); store.setSession(this.getSession()); • Enable session in view • Add stores to session
  • 69. Enable session CRM.model.Feedback.load('57d072659baeb676ced2b0e5',{ success:function(record){ this.getViewModel().set('feedback', record); }, scope:this }, this.getSession()); • Enable session in view • Add stores to session • Provide session in model load
  • 70. Enable session this.getViewModel().linkTo('companyProfile',{ type : 'CRM.model.CompanyProfile', id : '57bcbaa29baeb676ced2b0e0' });• Enable session in view • Add stores to session • Provide session in model load • Use LinkTo - uses session from viewModel
  • 73. Extra proxy parameters proxy: { type : 'ajax', extraParams:{ appName:'CRM' }, api : { read: '/companies', update: '/updateCompanies' }, reader:{ type:'json' }, writer:{ type : 'json', } } • Set in proxy using extraParams config
  • 74. Extra proxy parameters var proxy = Ext.ClassManager.get(<class>).getProxy(); proxy.setExtraParam('appName', 'CRM'); • Set in proxy using extraParams config • Set from controller using the setExtraParam function
  • 78. Handle error response { "IsSuccess": false, "ErrorMessage": "Missing company" }Error returned from the server in a json response when logic fails or data is missing.
  • 79. Configure the proxy reader proxy: { type : 'ajax', api : { read: '/companies', update: '/updateCompanies' }, reader:{ type:'json', successProperty:'IsSuccess', messageProperty:'ErrorMessage' } . . . • successProperty The property indicating that the operation was successful or not. • messageProperty The property where the error message is returned.
  • 80. Listen for proxy exception Ext.mixin.Observable.observe(Ext.data.proxy.Server); Ext.data.proxy.Server.on('exception', function(proxy, resp, operation){ Ext.Msg.alert('Error', operation.getError()); } ); • exception - fires when "success" is false - fires on HTTP exceptions • operation.getError() - returns messageProperty content
  • 82. Please Take the Survey in the Mobile App • Navigate to this session in the mobile app • Click on “Evaluate Session” • Respondents will be entered into a drawing to win one of five $50 Amazon gift cards

Notes de l'éditeur

  1. Its easy to write applications that are simple. You decide everything
  2. Refesh our memories
  3. The world smallest CRM system
  4. Beutiful application
  5. Binding has given us so mych power
  6. Create the actual view package
  7. Lets add some real world
  8. So common. Object/no sql
  9. Dates are from hell. I hate dates. with all my heart
  10. Most data Associate . Associations enable you to express relationships between different Ext.data.Model
  11. Our product owner demands a grid with licenses
  12. In most databases you reference using a "foreign key"
  13. Talk about different demands. Proxy is preffered
  14. This is a VERY common demand.
  15. Errors are standardized thrue the backend