HANNAH HOWARD #ABOUTME Personal hannah@carbon Anecdote: I have - - PowerPoint PPT Presentation

hannah howard aboutme
SMART_READER_LITE
LIVE PREVIEW

HANNAH HOWARD #ABOUTME Personal hannah@carbon Anecdote: I have - - PowerPoint PPT Presentation

HANNAH HOWARD #ABOUTME Personal hannah@carbon Anecdote: I have @techgirlwonder ve.com a dog she/her REACTIVE PROGRAMMING: A Better Way to Write Frontend Applications 1. PROBLEM STATEMENT WHAT IS A COMPUTER PROGRAM? A computer


slide-1
SLIDE 1

@techgirlwonder she/her hannah@carbon ve.com Personal Anecdote: I have a dog

HANNAH HOWARD #ABOUTME

slide-2
SLIDE 2

REACTIVE PROGRAMMING:

A Better Way to Write Frontend Applications

slide-3
SLIDE 3

1. PROBLEM STATEMENT

slide-4
SLIDE 4

WHAT IS A COMPUTER PROGRAM?

slide-5
SLIDE 5

A computer program is a sequence of instructions for performing a task designed to solve specic problems.

  • Wikipedia
slide-6
SLIDE 6

Program = Todo List?

'SEQUENCE OF INSTRUCTIONS'

slide-7
SLIDE 7

LESSON PLAN

slide-8
SLIDE 8

HOW COMPUTER PROGRAMS ACTUALLY RUN

slide-9
SLIDE 9

the heart of frontend programming

INTERRUPTIONS:

slide-10
SLIDE 10

2. A BRIEF HISTORY OF INTERRUPTIONS

slide-11
SLIDE 11

Technique 1:

GLOBAL EVENT BUS

slide-12
SLIDE 12

In The Beginning... C!

  • 1. #define BYTE unsigned char
  • 2. #define NUM_SCAN_QUE 256 // this MUST be 256, using BYTE

roll­over for \

  • 3. // q code
  • 4. BYTE gb_scan;
  • 5. BYTE gb_scan_q[NUM_SCAN_QUE];
  • 6. BYTE gb_scan_head;
  • 7. BYTE gb_scan_tail;

8.

  • 9. static void interrupt(far *oldkb)(void); /* BIOS keyboard

handler */ 10.

  • 11. /* ­­­­­­­­­­­­­­­­­­­­­­ get_scan() ­­­­­­­­­­­­­­­­­­­­­

April 17,1993 */

  • 12. void interrupt get_scan(void)
  • 13. {
  • 14. /* read the scan code from the keyboard */
slide-13
SLIDE 13

Windows event loop

  • 1. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE

hPrevInstance, LPSTR lpCmdLine, int nCmdShow)

  • 2. {
  • 3. MSG msg;
  • 4. BOOL bRet;

5.

  • 6. while (1)
  • 7. {
  • 8. bRet = GetMessage(&msg, NULL, 0, 0);

9.

  • 10. if (bRet > 0) // (bRet > 0 indicates a message that

must be processed.)

  • 11. {
  • 12. TranslateMessage(&msg);
  • 13. DispatchMessage(&msg);
slide-14
SLIDE 14
  • 1. LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM

wParam, LPARAM lParam) // second message parameter

  • 2. {
  • 3. switch (uMsg)
  • 4. {
  • 5. case WM_CREATE:
  • 6. // Initialize the window.
  • 7. return 0;

8.

  • 9. case WM_PAINT:
  • 10. // Paint the window's client area.
  • 11. return 0;

12.

  • 13. case WM_SIZE:
  • 14. // Set the size and position of the window.
  • 15. return 0;

16.

  • 17. case WM_DESTROY:
  • 18. // Clean up window­specific data objects.
  • 19. return 0;
  • 20. //

Window procedure = read message, update state

slide-15
SLIDE 15

1999?

slide-16
SLIDE 16
  • 1. LRESULT CALLBACK MainWndProc(HWND hwnd, UINT uMsg, WPARAM

wParam, LPARAM lParam) // second message parameter

  • 2. {
  • 3. switch (uMsg)
  • 4. {
  • 5. case WM_CREATE:
  • 6. // Initialize the window.
  • 7. return 0;

8.

  • 9. case WM_PAINT:
  • 10. // Paint the window's client area.
  • 11. return 0;

12.

  • 13. case WM_SIZE:
  • 14. // Set the size and position of the window.
  • 15. return 0;

16.

  • 17. case WM_DESTROY:
  • 18. // Clean up window­specific data objects.
  • 19. return 0;
  • 20. //
  • 21. // Process other messages.
  • 22. //

23. default: Or did we?

slide-17
SLIDE 17
  • 1. function todoApp(state = initialState, action) {
  • 2. switch (action.type) {
  • 3. case SET_VISIBILITY_FILTER:
  • 4. return { ...state,
  • 5. visibilityFilter: action.filter
  • 6. };
  • 7. case ADD_TODO:
  • 8. return { ...state,
  • 9. todos: [
slide-18
SLIDE 18

NO SHADE TO REDUX

slide-19
SLIDE 19

Technique 2:

OBSERVER PATTERN

slide-20
SLIDE 20

A SHORT DIGRESSION...

slide-21
SLIDE 21

VERY IMPORTANT CONTENT CREATOR

slide-22
SLIDE 22

HOW WILL PEOPLE SEE MY CONTENT?

slide-23
SLIDE 23

OLD SCHOOL WAY

slide-24
SLIDE 24

I will make content

  • inuencer

I will subscribe to your content

  • adoring fan

I made new content

  • inuencer

I am notied about your content, and can watch it

  • adoring fan
slide-25
SLIDE 25

I will emit events

  • Subject

I will subscribe to your events

  • Observer

An event happened

  • Subject

I am notied about the event, and can handle it

  • Observer
slide-26
SLIDE 26

Real World Example

  • 1. // Function to change the content of t2
  • 2. const modifyText = () => {
  • 3. const toggle = document.getElementById("toggle");
  • 4. toggle.firstChild.nodeValue = t2.firstChild.nodeValue ==

"on" ? "off" : "on";

  • 5. }

6.

  • 7. // add event listener to table
  • 8. const el = document.getElementById("toggle­switch");
  • 9. el.addEventListener("click", modifyText, false);
slide-27
SLIDE 27

OBSERVER PATTERN VS GLOBAL EVENT BUS

(+) Way simpler than global event bus (+) Localized scope (-) Have To Setup Subscriptions

slide-28
SLIDE 28

Take home quiz:

TRY DRAG AND DROP

slide-29
SLIDE 29

MIXING CONCERNS

  • 1. Handling events
  • 2. Subscribing observers
slide-30
SLIDE 30

Is this what happened?

REDUX ORIGIN STORY

slide-31
SLIDE 31

IS THERE A BETTER WAY?

slide-32
SLIDE 32

3. FUNCTIONAL REACTIVE PROGRAMMING

slide-33
SLIDE 33

I taught middle school

ONCE UPON A TIME...

slide-34
SLIDE 34

GOOD TEACHERS = JEDI

slide-35
SLIDE 35

DON'T START WITH A PLAN...

slide-36
SLIDE 36

AND GET INTERRUPTED.

slide-37
SLIDE 37

PLAN FOR INTERRUPTIONS AND REACT!

slide-38
SLIDE 38

PSA:

PAY TEACHERS

slide-39
SLIDE 39

HOW COULD WE WRITE PROGRAMS REACTIVELY?

slide-40
SLIDE 40

Consider this statement

Y = X + 3

slide-41
SLIDE 41

Assign once the value for y by adding 3 to x

IMPERATIVE MEANING:

slide-42
SLIDE 42

An equation

MATH MEANING

5 10 15 20 ­5 ­10 ­15 ­20 5 10 15 20 ­5 ­10 ­15 ­20 y x

slide-43
SLIDE 43

X is a value that can change over time. Y is always the value 3 greater than X

REACTIVE MEANING:

slide-44
SLIDE 44

a data stream of numbers over time

X VALUES OVER TIME

9 3 10 4

slide-45
SLIDE 45

a data stream of numbers derived from another stream

Y VALUES OVER TIME

9 3 10 4 3 12 6 13 7

slide-46
SLIDE 46

Stream of user input events

MOUSE CLICKS OVER TIME

MC MC MC MCMC MC MC MC MCMC MC MC

slide-47
SLIDE 47

REACTIVE PROGRAMMING IN THE REAL WORLD?

slide-48
SLIDE 48

Only better...

OBSERVER PATTERN!

slide-49
SLIDE 49

A value that changes over time, that we can listen to changes on

OBSERVABLE:

slide-50
SLIDE 50

Value as 'Observable'

  • 1. x.subscribe(nextX => console.log(nextX))

2.

  • 3. x.subscribe(nextX => console.log(nextX + 3))

4.

  • 5. y = "?";

6.

  • 7. x = [0, 9, 3, 10, 4]

8.

  • 9. y = x.map(nextX => nextX + 3)

10.

  • 11. x = Observable.of(0, 9, 3, 10, 4);

12.

  • 13. y = x.map(nextX => nextX + 3)
slide-51
SLIDE 51

Go Left Go Right Left Button Clicks Right Button Clicks Left Click Position Right Click Position Position

slide-52
SLIDE 52

How This Works

  • 1. import {
  • 2. fromEvent,
  • 3. merge
  • 4. } from "rxjs";
slide-53
SLIDE 53
  • 4. HOW DO I ACTUALLY USE THIS?
slide-54
SLIDE 54

IMPORTANT DATA POINT

slide-55
SLIDE 55

YOU'RE ALREADY USING IT.

slide-56
SLIDE 56

TWO QUESTIONS FOR USING RXJS

How to architect applications with RxJS? How do I integrate this in my application, today?

slide-57
SLIDE 57

User name: Password: Submit

User name Password Submit Button Login Attempts Login Responses Login In Progress Login Failures Login Successes Failure Message User Token Get Protected Protected Resourc

slide-58
SLIDE 58

But how tho?

  • 1. const api = {
  • 2. login: (username, password) => Promise,
  • 3. protectedResource: {
  • 4. get: (userToken) => Promise
  • 5. }
  • 6. };

7.

  • 8. const username$ = new Subject();
  • 9. const password$ = new Subject();
  • 10. const submitButton$ = new Subject();

11.

  • 12. const loginAttempts$ =

submitButton$.pipe(withLatestFrom(username$, password$)); 13.

  • 14. const loginResponses$ = loginAttempts$.pipe(
  • 15. mergeMap(([_, username, password]) => api.login(
  • 16. username,

17. password

slide-59
SLIDE 59

How data propogates through your program

SIGNAL GRAPH

slide-60
SLIDE 60

ACTUAL SIGNAL GRAPH FROM REAL APP

email password authorizationRequested selectedAccountIndex portfolioSelected authorization user failedLogins portfolios activePortfolio portfolioSecurities accounts activeAccount activeAccountPerformances activeAccountPortfolios
slide-61
SLIDE 61

PRODUCTION CONCERNS

  • 1. How do I test?
  • 2. How do I make sure my graph is sound?
  • 3. Ack RxJs idiosyncracies!
  • 4. One big graph or lots of smaller ones?
  • 5. Diagramming is hard
slide-62
SLIDE 62

I liked Signal Graphs so much I bought the company!

  • me, 2018
slide-63
SLIDE 63

A library for frontend state management using signal graphs

SIGNAL:

slide-64
SLIDE 64

Signal!

  • 1. const signalGraph = new SignalGraphBuilder()
  • 2. .define(
  • 3. addPrimary('username$'),
  • 4. addPrimary('password$'),
  • 5. addPrimary('submitButton$'),
  • 6. addDerived(
  • 7. 'loginAttempts$',
  • 8. makeLoginAttempts,
  • 9. 'submitButton$',
  • 10. 'username$',
  • 11. 'password$'
  • 12. ),
  • 13. addDerived('loginResponses$', makeLoginResponses,

'loginAttempts$', 'api'),

  • 14. addDerived(
  • 15. 'loginInProgress$',
  • 16. makeLoginInProgress,

17. 'loginAttempts$',

slide-65
SLIDE 65

Available Now(ish):

@RXREACT/SIGNAL

slide-66
SLIDE 66

Coming Soon:

AUTOMATIC GRAPH VISUALIZATION

slide-67
SLIDE 67

INTEGRATION

slide-68
SLIDE 68

FRAMEWORK = ANGULAR

  • 1. You're done
  • 2. Check out NgRx
slide-69
SLIDE 69

BUT WHAT ABOUT REACT?

slide-70
SLIDE 70

GOOD NEWS!

slide-71
SLIDE 71

Tools for integrating react with RxJs!

RXREACT:

slide-72
SLIDE 72

Signal-connect

  • 1. import { withViewModel } from '@rxreact/signal­connect'

2.

  • 3. const PositionedBox = ({ position }) => <RedBox pose=

{position} /> 4.

  • 5. const ballSignalGraph = new

SignalGraphBuilder().define(/*...*/).build() 6.

  • 7. // connect(graph, mapGraphOutputsToProps,

mapGraphInputsToProps = {})

  • 8. const BoundBox = connect(
  • 9. ballSignalGraph,
  • 10. {
  • 11. position: 'position$'
  • 12. }
  • 13. )(PositionedBox)

14.

  • 15. const LeftButton = connect(
slide-73
SLIDE 73

5. USED CAR SALES PORTION

slide-74
SLIDE 74

RxJs+React on it's own

@RXREACT/CORE:

slide-75
SLIDE 75

RxReact Demo

  • 1. import { withViewModel } from '@rxreact/core'

2.

  • 3. const PositionedBox = ({ position }) => <RedBox pose=

{position} /> 4.

  • 5. const boxVm = {
  • 6. inputs: {
  • 7. position: position$
  • 8. }
  • 9. }

10.

  • 11. const BoundBox = withViewModel(boxVm)(PositionedBox)

12.

  • 13. const LeftButton = withViewModel({
  • 14. outputs: {
  • 15. onClick: leftClick$
  • 16. }
slide-76
SLIDE 76

WHAT ABOUT TYPESCRIPT?

slide-77
SLIDE 77

RXREACT TYPESCRIPT

slide-78
SLIDE 78

VIEW MODEL AS REDUCER?

slide-79
SLIDE 79
  • 1. let viewModel = viewModelFromReducer({
  • 2. initialState: {
  • 3. count: 2,
  • 4. fruit: 'bananas',
  • 5. extra: 'applesauce'
  • 6. },
  • 7. reducer(state, action) {
  • 8. switch (action.type) {
  • 9. case ActionType.SET_COUNT:
  • 10. return ReducerResult.Update({ ...state,
  • 11. count: action.payload
slide-80
SLIDE 80

@RXREACT/PROCESS

slide-81
SLIDE 81

reactivex-talk.techgirlwonder.com github.com/hannahhoward/reactivex-talk

THAT'S ALL FOLKS!