Slide 1

Slide 1 text

Data Loading Patterns EmberFest, Budapest, 10/28/2016

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

This talk is going to be … • A series of prevalent use cases • Rich in code examples • Packed with actionable advice

Slide 5

Slide 5 text

Ember Data: 60% Ember: 30% json:api: 10%

Slide 6

Slide 6 text

Covering the basics

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

1. Aquincum 2. Pannonia 3. Hungaricum There was a Roman settlement where today there is Budapest. What was its name back then?

Slide 11

Slide 11 text

1. Aquincum 2. Pannonia 3. Hungaricum There was a Roman settlement where today there is Budapest. What was its name back then?

Slide 12

Slide 12 text

1. 1918 2. 1686 3. 1873 Budapest came into being as the unification of Buda, Óbuda and Pest. When?

Slide 13

Slide 13 text

1. 1918 2. 1686 3. 1873 Budapest came into being as the unification of Buda, Óbuda and Pest. When?

Slide 14

Slide 14 text

1. 44 2. 26 3. 34 How many letters does the Hungarian alphabet have?

Slide 15

Slide 15 text

1. 44 2. 26 3. 34 How many letters does the Hungarian alphabet have?

Slide 16

Slide 16 text

Piece of cake.

Slide 17

Slide 17 text

Ember Data?

Slide 18

Slide 18 text

1. Returns null 2. Returns an Ember.ObjectProxy, sends a request for that band and eventually resolves with the returned record 3. Returns undefined What does store.findRecord(‘band’, 1) do if the record is NOT in the store?

Slide 19

Slide 19 text

1. Returns null 2. Returns an Ember.ObjectProxy, sends a request for that band and eventually resolves with the returned record 3. Returns undefined What does store.findRecord(‘band’, 1) do if the record is NOT in the store?

Slide 20

Slide 20 text

1. Returns an Ember.ObjectProxy with the record and triggers a background refetching of the record 2. Returns an Ember.ObjectProxy with the record 3. Returns the record What does store.findRecord(‘band’, 1) do if the record is in the store?

Slide 21

Slide 21 text

1. Returns an Ember.ObjectProxy with the record and triggers a background refetching of the record 2. Returns an Ember.ObjectProxy with the record 3. Returns the record What does store.findRecord(‘band’, 1) do if the record is in the store?

Slide 22

Slide 22 text

1. Returns an array with the bands in the store 2. Returns an Ember.ArrayProxy with the records in the store 3. Returns an Ember.ArrayProxy with the records in the store and triggers a background refetching of all bands What does store.findAll(‘band’) do if there is at least one band in the store?

Slide 23

Slide 23 text

1. Returns an array with the bands in the store 2. Returns an Ember.ArrayProxy with the records in the store 3. Returns an Ember.ArrayProxy with the records in the store and triggers a background refetching of all bands What does store.findAll(‘band’) do if there is at least one band in the store?

Slide 24

Slide 24 text

1. Returns an Ember.ArrayProxy with the bands in the store and triggers a background request to fetch all of them 2. Returns an Ember.ArrayProxy with the bands in the store 3. Returns an array with the bands in the store What does store.peekAll(‘band’) do if there is at least one band in the store?

Slide 25

Slide 25 text

1. Returns an Ember.ArrayProxy with the bands in the store and triggers a background request to fetch all of them 2. Returns an Ember.ArrayProxy with the bands in the store 3. Returns an array with the bands in the store What does store.peekAll(‘band’) do if there is at least one band in the store?

Slide 26

Slide 26 text

1. Returns an Ember.ArrayProxy and triggers a request to fetch all bands in the background 2. Returns undefined 3. Returns an Ember.ArrayProxy backed by an empty array What does store.peekAll(‘band’) do if there are NO bands in the store?

Slide 27

Slide 27 text

What does store.peekAll(‘band’) do if there are NO bands in the store? 1. Returns an Ember.ArrayProxy and triggers a request to fetch all bands in the background 2. Returns undefined 3. Returns an Ember.ArrayProxy backed by an empty array

Slide 28

Slide 28 text

shouldBackgroundReload* • shouldBackgroundReloadRecord • shouldBackgroundReloadAll • configurable on the adapter, true by default

Slide 29

Slide 29 text

What does the model hook return if it’s not defined? 1. The value its parent route returned 2. undefined 3. An instance of FieldServerTaskMappingPrototypePool

Slide 30

Slide 30 text

What does the model hook return if it’s not defined? 1. The value its parent route returned 2. undefined 3. An instance of FieldServerTaskMappingPrototypePool

Slide 31

Slide 31 text

Resolving model hooks • The model hooks are resolved top-down • A child route is not entered before the hooks are run for its parent

Slide 32

Slide 32 text

“Blocking” template rendering • Returning a promise in the model hook “blocks” rendering the page • `findRecord`, `findAll`, `query` all return promises

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Balint Erdi @baaz balinterdi balinterdi.com [email protected] Rock and Roll with Ember.js

Slide 35

Slide 35 text

Case studies

Slide 36

Slide 36 text

application bands bands.band.songs bands.band

Slide 37

Slide 37 text

Reload a record in the background

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

Why doesn’t the band name get updated?

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

The greatest Ember gotcha ever.

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

`shouldBackgroundReloadRecord` is great and it just works

Slide 45

Slide 45 text

Don’t pass in a model object to {{link-to …}}

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

Reload a collection in the background

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

`shouldBackgroundReloadAll` is great and it just works

Slide 51

Slide 51 text

Fetching relationship data

Slide 52

Slide 52 text

Lazy fetching

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

No content

Slide 55

Slide 55 text

Pros & cons • Simple, works out of the box • No superfluous data fetching • Disturbing flicker

Slide 56

Slide 56 text

Pre-loading the async relationship

Slide 57

Slide 57 text

No content

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Move relationship data fetching to the route’s model hook if you want to block rendering

Slide 60

Slide 60 text

Pros & cons • Better UX than the lazy fetching scenario • RSVP.hash in the model hook is considered an anti-pattern

Slide 61

Slide 61 text

Side-loading

Slide 62

Slide 62 text

No content

Slide 63

Slide 63 text

No content

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

No content

Slide 66

Slide 66 text

Why is there a flicker? Shouldn’t the songs be side-loaded and only then the page rendered?

Slide 67

Slide 67 text

No content

Slide 68

Slide 68 text

No content

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

No content

Slide 71

Slide 71 text

Searching on the backend

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

json:api compliance • filter[field]=value • json:api libraries have support for it • `store.query(‘song’, { filter: { title: ‘smoke’ } })` • `band.get(‘songs’).query({ filter: { title: ‘smoke’ } })`

Slide 76

Slide 76 text

No content

Slide 77

Slide 77 text

Indicating ongoing record fetching

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

No content

Slide 80

Slide 80 text

No content

Slide 81

Slide 81 text

Use the `loading` event to customize the UX for indicating loading

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

Indicating ongoing background record fetching

Slide 84

Slide 84 text

No content

Slide 85

Slide 85 text

No content

Slide 86

Slide 86 text

No content

Slide 87

Slide 87 text

No content

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

No content

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

Leverage `findAll(…, { reload: true })` to have more control over the loading process

Slide 92

Slide 92 text

Learn ember-concurrency

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

Director’s cut • Partial loading records • Symmetrical relationships

Slide 95

Slide 95 text

balinterdi/ember-data-patterns

Slide 96

Slide 96 text

No content

Slide 97

Slide 97 text

References • Rock and Roll with Ember book • Lessons learned from four years with Ember by Ryan Toronto • ember-concurrency