SlideShare a Scribd company logo
SQLite & ORM Binding - Part II
Now that we covered the basic persistence abstraction lets proceed to integrate it into the app
Integrating Persistence
✦If there are no dishes we load them from the app
storage in the dishes list
© Codename One 2017 all rights reserved
if(Restaurant.getInstance().menu.get().dishes.size() == 0) {
for(PropertyBusinessObject d : AppStorage.getInstance().fetchDishes()) {
Restaurant.getInstance().menu.get().dishes.add((Dish)d);
}
}
for(Dish d : Restaurant.getInstance().menu.get().dishes) {
addDish(app, d);
}
We fetch dishes as we need them implicitly from storage, this is pretty simple code that just adds all the dish elements to the dishes list property
Integrating Persistence
✦We use the delete listener to refresh the UI after
deletion
© Codename One 2017 all rights reserved
AppStorage.getInstance().addDeleteListener(e -> {
for(Component cmp : getContentPane()) {
Dish d = (Dish)cmp.getClientProperty("dish");
if(d == e.getSource()) {
cmp.remove();
revalidate();
return;
}
}
});
As I mentioned before the dish list form needs to detect the deletion of a dish so it can remove it from the UI. We do this by binding a delete listener and removing the
element.
Property Binding
✦If the properties change (when data is persisted) we
map that to the UI of the dish in the main dish list
© Codename One 2017 all rights reserved
public void addDish(AppSettings app, Dish d) {
ScaleImageButton sb = new ScaleImageButton(d.getFullSize());
sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
Label title = new Label(d.name.get(), "DishName");
d.name.addChangeListener(pl -> title.setText(d.name.get()));
Label description = new Label(d.description.get(), "DishDescription");
d.description.addChangeListener(pl -> description.setText(d.description.get()));
One of the really cool things about properties is the ability to bind property change listeners to properties so we can decouple code that uses the same data model to
display a view in two different places. 

I wrote this code before the ui binding API code existed in Codename One but it’s pretty trivial either way, I just update the text when the property changes.
delete.addActionListener(e -> {
previous.addShowListener(prev -> {
previous.removeAllShowListeners();
ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”,
FontImage.MATERIAL_UNDO, ee -> {
DishListForm dlf = (DishListForm)previous;
dlf.addDish(app, d);
d.id.set(null);
bld.addDish(app, d);
d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d));
});
});
previous.showBack();
bld.deleteDish(app, d);
AppStorage.getInstance().delete(d);
});
DishEditForm
It's Better to Beg for Forgiveness than to Ask for Permission is a proverb sometimes attributed to programming pioneer Grace Hopper. Regardless of the source of that
great quote it’s a wonderful example of good mobile app design. In a mobile app you shouldn’t bother users with “Are you sure” prompts. You should just do what the
user does and provide a way to undo which is exactly what we do when we delete a dish in this code…
delete.addActionListener(e -> {
previous.addShowListener(prev -> {
previous.removeAllShowListeners();
ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”,
FontImage.MATERIAL_UNDO, ee -> {
DishListForm dlf = (DishListForm)previous;
dlf.addDish(app, d);
d.id.set(null);
bld.addDish(app, d);
d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d));
});
});
previous.showBack();
bld.deleteDish(app, d);
AppStorage.getInstance().delete(d);
});
DishEditForm
I’ll skip a bit ahead because the code above is asynchronous. When delete is pressed we show the previous dish list form since the edit form is no longer applicable.
Then we delete the dish in the server and in the storage. You will notice that there is no prompt.
delete.addActionListener(e -> {
previous.addShowListener(prev -> {
previous.removeAllShowListeners();
ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”,
FontImage.MATERIAL_UNDO, ee -> {
DishListForm dlf = (DishListForm)previous;
dlf.addDish(app, d);
d.id.set(null);
bld.addDish(app, d);
d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d));
});
});
previous.showBack();
bld.deleteDish(app, d);
AppStorage.getInstance().delete(d);
});
DishEditForm
Now we need to show a UI that allows the user to undo the delete operation but here is the problem… We just navigated to the dish list from the form we were in since
the edit form is no longer applicable. So we use a listener on the parent form so we will know when it is shown again. The problem is that if we do that without the next
line we’ll get prompts every time we enter that form after the deletion.

So the obvious question is: why didn’t we just call removeShowListener(this). Well, funny story… This is a lambda expression and here this is always the parent class so
removeShowListener(this) won’t have the desired affect. So the solution is a bit of a hack but it was either this or use inner classes so I chose this hack.
delete.addActionListener(e -> {
previous.addShowListener(prev -> {
previous.removeAllShowListeners();
ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”,
FontImage.MATERIAL_UNDO, ee -> {
DishListForm dlf = (DishListForm)previous;
dlf.addDish(app, d);
d.id.set(null);
bld.addDish(app, d);
d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d));
});
});
previous.showBack();
bld.deleteDish(app, d);
AppStorage.getInstance().delete(d);
});
DishEditForm
This is relatively simple, we are now in the right form after the deletion and I can now show the undo toast message that will appear in the bottom of the form. If a user
taps this popup it will undo the deletion instantly
delete.addActionListener(e -> {
previous.addShowListener(prev -> {
previous.removeAllShowListeners();
ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”,
FontImage.MATERIAL_UNDO, ee -> {
DishListForm dlf = (DishListForm)previous;
dlf.addDish(app, d);
d.id.set(null);
bld.addDish(app, d);
d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d));
});
});
previous.showBack();
bld.deleteDish(app, d);
AppStorage.getInstance().delete(d);
});
DishEditForm
The undo code doesn’t really “undo” as there is no meaningful way to undo in code. We just re-add the dish.
ok.addActionListener(e -> {
previous.showBack();
d.name.set(title.getText());
d.description.set(description.getText());
try {
d.price.set(Double.parseDouble(price.getText()));
} catch(NumberFormatException err) {
Log.e(err);
ToastBar.showErrorMessage("Malformed price");
}
bld.updateDish(app, d);
Restaurant.getInstance().menu.get().dishes.add(d);
if(d.id.get() != null) {
AppStorage.getInstance().update(d);
}
//bld.updateDishImage(app, d);
});
DishEditForm
By comparison saving the dish is much easier and practically trivial. All of the logic to save a dish to the server and update it to storage is just a couple of lines of code
TextField title = new TextField(app.name.get());
title.setUIID("NavigationTitle");
title.addActionListener(a -> {
app.name.set(title.getText());
AppStorage.getInstance().update(app);
});
TextField tagline = new TextField(app.tagline.get());
tagline.setUIID("Tagline");
tagline.addActionListener(a -> {
app.tagline.set(tagline.getText());
AppStorage.getInstance().update(app);
});
BaseNavigationForm
In the case of the tagline & title we currently only save them locally but we will add the server update code as well
Thank You
Thanks for watching. I hope you found this informative

More Related Content

Similar to SQLite and ORM Binding - Part 2 - Transcript.pdf

Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.jsChris Saylor
 
Initial UI Mockup - Part 3 - Transcript.pdf
Initial UI Mockup - Part 3 - Transcript.pdfInitial UI Mockup - Part 3 - Transcript.pdf
Initial UI Mockup - Part 3 - Transcript.pdfShaiAlmog1
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfShaiAlmog1
 
Adapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdfAdapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdfShaiAlmog1
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionDzmitry Ivashutsin
 
Adapting to Tablets and Desktops - Part 3 - Transcript.pdf
Adapting to Tablets and Desktops - Part 3 - Transcript.pdfAdapting to Tablets and Desktops - Part 3 - Transcript.pdf
Adapting to Tablets and Desktops - Part 3 - Transcript.pdfShaiAlmog1
 
Unit5 Mobile Application Development.doc
Unit5 Mobile Application Development.docUnit5 Mobile Application Development.doc
Unit5 Mobile Application Development.docKNANTHINIMCA
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingCodemotion
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!Sébastien Levert
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfShaiAlmog1
 
Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?GlobalLogic Ukraine
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in AndroidRobert Cooper
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfShaiAlmog1
 
Adapting to Tablets and Desktops - Part 1.pdf
Adapting to Tablets and Desktops - Part 1.pdfAdapting to Tablets and Desktops - Part 1.pdf
Adapting to Tablets and Desktops - Part 1.pdfShaiAlmog1
 

Similar to SQLite and ORM Binding - Part 2 - Transcript.pdf (20)

Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.js
 
Initial UI Mockup - Part 3 - Transcript.pdf
Initial UI Mockup - Part 3 - Transcript.pdfInitial UI Mockup - Part 3 - Transcript.pdf
Initial UI Mockup - Part 3 - Transcript.pdf
 
Creating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdfCreating a Facebook Clone - Part XXIX - Transcript.pdf
Creating a Facebook Clone - Part XXIX - Transcript.pdf
 
Adapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdfAdapting to Tablets and Desktops - Part 3.pdf
Adapting to Tablets and Desktops - Part 3.pdf
 
ngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency InjectionngMess: AngularJS Dependency Injection
ngMess: AngularJS Dependency Injection
 
React lecture
React lectureReact lecture
React lecture
 
Adapting to Tablets and Desktops - Part 3 - Transcript.pdf
Adapting to Tablets and Desktops - Part 3 - Transcript.pdfAdapting to Tablets and Desktops - Part 3 - Transcript.pdf
Adapting to Tablets and Desktops - Part 3 - Transcript.pdf
 
Unit5 Mobile Application Development.doc
Unit5 Mobile Application Development.docUnit5 Mobile Application Development.doc
Unit5 Mobile Application Development.doc
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!SharePoint Conference 2018 - APIs, APIs everywhere!
SharePoint Conference 2018 - APIs, APIs everywhere!
 
From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Android 3
Android 3Android 3
Android 3
 
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdfCreating a Facebook Clone - Part XXVIII - Transcript.pdf
Creating a Facebook Clone - Part XXVIII - Transcript.pdf
 
Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?Data Binding: Is It the Next Big Thing?
Data Binding: Is It the Next Big Thing?
 
What's New in Android
What's New in AndroidWhat's New in Android
What's New in Android
 
shiny.pdf
shiny.pdfshiny.pdf
shiny.pdf
 
Creating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdfCreating an Uber Clone - Part XXXX.pdf
Creating an Uber Clone - Part XXXX.pdf
 
Adapting to Tablets and Desktops - Part 1.pdf
Adapting to Tablets and Desktops - Part 1.pdfAdapting to Tablets and Desktops - Part 1.pdf
Adapting to Tablets and Desktops - Part 1.pdf
 
Day 5
Day 5Day 5
Day 5
 
resume_Alexey_Zaytsev
resume_Alexey_Zaytsevresume_Alexey_Zaytsev
resume_Alexey_Zaytsev
 

More from ShaiAlmog1

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...ShaiAlmog1
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfShaiAlmog1
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfShaiAlmog1
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfShaiAlmog1
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfShaiAlmog1
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfShaiAlmog1
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfShaiAlmog1
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfShaiAlmog1
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfShaiAlmog1
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfShaiAlmog1
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfShaiAlmog1
 

More from ShaiAlmog1 (20)

The Duck Teaches Learn to debug from the masters. Local to production- kill ...
The Duck Teaches  Learn to debug from the masters. Local to production- kill ...The Duck Teaches  Learn to debug from the masters. Local to production- kill ...
The Duck Teaches Learn to debug from the masters. Local to production- kill ...
 
create-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdfcreate-netflix-clone-06-client-ui.pdf
create-netflix-clone-06-client-ui.pdf
 
create-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdfcreate-netflix-clone-01-introduction_transcript.pdf
create-netflix-clone-01-introduction_transcript.pdf
 
create-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdfcreate-netflix-clone-02-server_transcript.pdf
create-netflix-clone-02-server_transcript.pdf
 
create-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdfcreate-netflix-clone-04-server-continued_transcript.pdf
create-netflix-clone-04-server-continued_transcript.pdf
 
create-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdfcreate-netflix-clone-01-introduction.pdf
create-netflix-clone-01-introduction.pdf
 
create-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdfcreate-netflix-clone-06-client-ui_transcript.pdf
create-netflix-clone-06-client-ui_transcript.pdf
 
create-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdfcreate-netflix-clone-03-server.pdf
create-netflix-clone-03-server.pdf
 
create-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdfcreate-netflix-clone-04-server-continued.pdf
create-netflix-clone-04-server-continued.pdf
 
create-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdfcreate-netflix-clone-05-client-model_transcript.pdf
create-netflix-clone-05-client-model_transcript.pdf
 
create-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdfcreate-netflix-clone-03-server_transcript.pdf
create-netflix-clone-03-server_transcript.pdf
 
create-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdfcreate-netflix-clone-02-server.pdf
create-netflix-clone-02-server.pdf
 
create-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdfcreate-netflix-clone-05-client-model.pdf
create-netflix-clone-05-client-model.pdf
 
Creating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdfCreating a Whatsapp Clone - Part II.pdf
Creating a Whatsapp Clone - Part II.pdf
 
Creating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdfCreating a Whatsapp Clone - Part IX - Transcript.pdf
Creating a Whatsapp Clone - Part IX - Transcript.pdf
 
Creating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdfCreating a Whatsapp Clone - Part II - Transcript.pdf
Creating a Whatsapp Clone - Part II - Transcript.pdf
 
Creating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdfCreating a Whatsapp Clone - Part V - Transcript.pdf
Creating a Whatsapp Clone - Part V - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdfCreating a Whatsapp Clone - Part IV - Transcript.pdf
Creating a Whatsapp Clone - Part IV - Transcript.pdf
 
Creating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdfCreating a Whatsapp Clone - Part IV.pdf
Creating a Whatsapp Clone - Part IV.pdf
 
Creating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdfCreating a Whatsapp Clone - Part I - Transcript.pdf
Creating a Whatsapp Clone - Part I - Transcript.pdf
 

Recently uploaded

Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationZilliz
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlPeter Udo Diehl
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessUXDXConf
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxJennifer Lim
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfFIDO Alliance
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...FIDO Alliance
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024Stephanie Beckett
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeCzechDreamin
 
Buy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdfBuy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdfEasyPrinterHelp
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...CzechDreamin
 
Buy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptxBuy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptxEasyPrinterHelp
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityScyllaDB
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxAbida Shariff
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?Mark Billinghurst
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Julian Hyde
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...FIDO Alliance
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2DianaGray10
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Patrick Viafore
 

Recently uploaded (20)

Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo DiehlFuture Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
Future Visions: Predictions to Guide and Time Tech Innovation, Peter Udo Diehl
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
ASRock Industrial FDO Solutions in Action for Industrial Edge AI _ Kenny at A...
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Buy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdfBuy Epson EcoTank L3210 Colour Printer Online.pdf
Buy Epson EcoTank L3210 Colour Printer Online.pdf
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Buy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptxBuy Epson EcoTank L3210 Colour Printer Online.pptx
Buy Epson EcoTank L3210 Colour Printer Online.pptx
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 

SQLite and ORM Binding - Part 2 - Transcript.pdf

  • 1. SQLite & ORM Binding - Part II Now that we covered the basic persistence abstraction lets proceed to integrate it into the app
  • 2. Integrating Persistence ✦If there are no dishes we load them from the app storage in the dishes list © Codename One 2017 all rights reserved if(Restaurant.getInstance().menu.get().dishes.size() == 0) { for(PropertyBusinessObject d : AppStorage.getInstance().fetchDishes()) { Restaurant.getInstance().menu.get().dishes.add((Dish)d); } } for(Dish d : Restaurant.getInstance().menu.get().dishes) { addDish(app, d); } We fetch dishes as we need them implicitly from storage, this is pretty simple code that just adds all the dish elements to the dishes list property
  • 3. Integrating Persistence ✦We use the delete listener to refresh the UI after deletion © Codename One 2017 all rights reserved AppStorage.getInstance().addDeleteListener(e -> { for(Component cmp : getContentPane()) { Dish d = (Dish)cmp.getClientProperty("dish"); if(d == e.getSource()) { cmp.remove(); revalidate(); return; } } }); As I mentioned before the dish list form needs to detect the deletion of a dish so it can remove it from the UI. We do this by binding a delete listener and removing the element.
  • 4. Property Binding ✦If the properties change (when data is persisted) we map that to the UI of the dish in the main dish list © Codename One 2017 all rights reserved public void addDish(AppSettings app, Dish d) { ScaleImageButton sb = new ScaleImageButton(d.getFullSize()); sb.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL); Label title = new Label(d.name.get(), "DishName"); d.name.addChangeListener(pl -> title.setText(d.name.get())); Label description = new Label(d.description.get(), "DishDescription"); d.description.addChangeListener(pl -> description.setText(d.description.get())); One of the really cool things about properties is the ability to bind property change listeners to properties so we can decouple code that uses the same data model to display a view in two different places. I wrote this code before the ui binding API code existed in Codename One but it’s pretty trivial either way, I just update the text when the property changes.
  • 5. delete.addActionListener(e -> { previous.addShowListener(prev -> { previous.removeAllShowListeners(); ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”, FontImage.MATERIAL_UNDO, ee -> { DishListForm dlf = (DishListForm)previous; dlf.addDish(app, d); d.id.set(null); bld.addDish(app, d); d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d)); }); }); previous.showBack(); bld.deleteDish(app, d); AppStorage.getInstance().delete(d); }); DishEditForm It's Better to Beg for Forgiveness than to Ask for Permission is a proverb sometimes attributed to programming pioneer Grace Hopper. Regardless of the source of that great quote it’s a wonderful example of good mobile app design. In a mobile app you shouldn’t bother users with “Are you sure” prompts. You should just do what the user does and provide a way to undo which is exactly what we do when we delete a dish in this code…
  • 6. delete.addActionListener(e -> { previous.addShowListener(prev -> { previous.removeAllShowListeners(); ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”, FontImage.MATERIAL_UNDO, ee -> { DishListForm dlf = (DishListForm)previous; dlf.addDish(app, d); d.id.set(null); bld.addDish(app, d); d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d)); }); }); previous.showBack(); bld.deleteDish(app, d); AppStorage.getInstance().delete(d); }); DishEditForm I’ll skip a bit ahead because the code above is asynchronous. When delete is pressed we show the previous dish list form since the edit form is no longer applicable. Then we delete the dish in the server and in the storage. You will notice that there is no prompt.
  • 7. delete.addActionListener(e -> { previous.addShowListener(prev -> { previous.removeAllShowListeners(); ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”, FontImage.MATERIAL_UNDO, ee -> { DishListForm dlf = (DishListForm)previous; dlf.addDish(app, d); d.id.set(null); bld.addDish(app, d); d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d)); }); }); previous.showBack(); bld.deleteDish(app, d); AppStorage.getInstance().delete(d); }); DishEditForm Now we need to show a UI that allows the user to undo the delete operation but here is the problem… We just navigated to the dish list from the form we were in since the edit form is no longer applicable. So we use a listener on the parent form so we will know when it is shown again. The problem is that if we do that without the next line we’ll get prompts every time we enter that form after the deletion. So the obvious question is: why didn’t we just call removeShowListener(this). Well, funny story… This is a lambda expression and here this is always the parent class so removeShowListener(this) won’t have the desired affect. So the solution is a bit of a hack but it was either this or use inner classes so I chose this hack.
  • 8. delete.addActionListener(e -> { previous.addShowListener(prev -> { previous.removeAllShowListeners(); ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”, FontImage.MATERIAL_UNDO, ee -> { DishListForm dlf = (DishListForm)previous; dlf.addDish(app, d); d.id.set(null); bld.addDish(app, d); d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d)); }); }); previous.showBack(); bld.deleteDish(app, d); AppStorage.getInstance().delete(d); }); DishEditForm This is relatively simple, we are now in the right form after the deletion and I can now show the undo toast message that will appear in the bottom of the form. If a user taps this popup it will undo the deletion instantly
  • 9. delete.addActionListener(e -> { previous.addShowListener(prev -> { previous.removeAllShowListeners(); ToastBar.showMessage("Deleted " + d.name.get() + ". Undo?”, FontImage.MATERIAL_UNDO, ee -> { DishListForm dlf = (DishListForm)previous; dlf.addDish(app, d); d.id.set(null); bld.addDish(app, d); d.id.addChangeListener(pl -> AppStorage.getInstance().insert(d)); }); }); previous.showBack(); bld.deleteDish(app, d); AppStorage.getInstance().delete(d); }); DishEditForm The undo code doesn’t really “undo” as there is no meaningful way to undo in code. We just re-add the dish.
  • 10. ok.addActionListener(e -> { previous.showBack(); d.name.set(title.getText()); d.description.set(description.getText()); try { d.price.set(Double.parseDouble(price.getText())); } catch(NumberFormatException err) { Log.e(err); ToastBar.showErrorMessage("Malformed price"); } bld.updateDish(app, d); Restaurant.getInstance().menu.get().dishes.add(d); if(d.id.get() != null) { AppStorage.getInstance().update(d); } //bld.updateDishImage(app, d); }); DishEditForm By comparison saving the dish is much easier and practically trivial. All of the logic to save a dish to the server and update it to storage is just a couple of lines of code
  • 11. TextField title = new TextField(app.name.get()); title.setUIID("NavigationTitle"); title.addActionListener(a -> { app.name.set(title.getText()); AppStorage.getInstance().update(app); }); TextField tagline = new TextField(app.tagline.get()); tagline.setUIID("Tagline"); tagline.addActionListener(a -> { app.tagline.set(tagline.getText()); AppStorage.getInstance().update(app); }); BaseNavigationForm In the case of the tagline & title we currently only save them locally but we will add the server update code as well
  • 12. Thank You Thanks for watching. I hope you found this informative