Dan Schultz
danschultz
danschultzonline
Lead frontend engineer
Mixbook
Slide 3
Slide 3 text
montagebook.com
Slide 4
Slide 4 text
MY
BACKGROUND
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
BUT TODAY…
THE WEB IS A
DIFFERENT
WORLD
Slide 7
Slide 7 text
OPEN IS
AWESOME!
Slide 8
Slide 8 text
BUT
IT’S LACKING
Slide 9
Slide 9 text
?
DART
JAVASCRIPT
Slide 10
Slide 10 text
JAVASCRIPT
Slide 11
Slide 11 text
LIBRARY
OVERLOAD
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
NO CUSTOM
TYPES
Slide 14
Slide 14 text
KEEP ON
TRUCKIN’
Slide 15
Slide 15 text
ACCESSING NON-EXISTENT PROPERTIES
It’ll run but doesn’t do the right thing
var request = new XMLHttpRequest();
!
request.onreadystatechange = function() {
if (request.readystate == 4) {
console.log('Request done: ' + request.responseText);
}
};
Slide 16
Slide 16 text
INADEQUATE FOR
BUILDING LARGE
WEB APPS
Slide 17
Slide 17 text
DART
Slide 18
Slide 18 text
• Structured language
• Libraries
• Tools
• VM
Slide 19
Slide 19 text
TARGETS ALL MAJOR BROWSERS
Slide 20
Slide 20 text
LANGUAGE
TOUR
Slide 21
Slide 21 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
FA
M
IL
IA
R
Slide 22
Slide 22 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
NAMESPACES!
FA
M
IL
IA
R
Slide 23
Slide 23 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
CODE IMPORTS!
FA
M
IL
IA
R
Slide 24
Slide 24 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
FAMILIAR
FA
M
IL
IA
R
Slide 25
Slide 25 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
TERSE
FA
M
IL
IA
R
Slide 26
Slide 26 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
OPERATOR OVERLOADING
FA
M
IL
IA
R
Slide 27
Slide 27 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
ONE LINE FUNCTIONS
FA
M
IL
IA
R
Slide 28
Slide 28 text
library myApp.geom;
!
import "package:hash/hash.dart";
!
class Point {
num x;
num y;
!
Point(this.x, this.y);
!
Point operator +(Point other) {
return new Point(x + other.x, y + other.y);
}
String toString() => "{x: $x, y: $y}";
}
LANGUAGE TOUR
STRING INTERPOLATION
FA
M
IL
IA
R
Slide 29
Slide 29 text
LEXICAL SCOPING
FA
M
IL
IA
R
class CustomButton {
Element _hitArea;
!
CustomButton() {
_hitArea.onClick.listen((event) {
this.sayHi();
});
}
!
void sayHi() {
print("Hi!");
}
}
Slide 30
Slide 30 text
MIXINS
N
E
W
IS
H
OBSERVABLE
Don’t pollute your inheritance trees
PERSON
USER
Wait, dude..
am I really a
Persistable?
PERSISTABLE
Slide 31
Slide 31 text
MIXINS
N
E
W
IS
H
PERSON
Don’t pollute your inheritance trees
PERSISTABLE
USER MIXIN
OBSERVABLE
Slide 32
Slide 32 text
MIXINS
N
E
W
IS
H
Don’t pollute your inheritance trees
class Persistable {
save() { … }
load() { … }
toJson() { … }
}
class
}
class Observable {
Stream get changes { … }
!
void changed(property, value) { … }
}
void
var
user
}
Slide 33
Slide 33 text
MIXINS
N
E
W
IS
H
Don’t pollute your inheritance trees
class User extends Person with Persistable, Observable {
}
void
var
user
}
APPLY THE MIXIN
class
save() { … }
load()
toJson()
}
class
Stream get changes
!
}
Slide 34
Slide 34 text
MIXINS
N
E
W
IS
H
Don’t pollute your inheritance trees
class User extends Person with Persistable, Observable {
}
void main() {
var user = new User();
user.save();
}
APPLY THE MIXIN
USE THE MIXIN’S METHODS
class
save() { … }
load()
toJson()
}
class
Stream get changes
!
}
Slide 35
Slide 35 text
ANNOTATIONS
N
E
W
IS
H
METADATA
Slide 36
Slide 36 text
ANNOTATIONS
N
E
W
IS
H
WARNING
Slide 37
Slide 37 text
ANNOTATIONS
N
E
W
IS
H
Create your own!
class User extends Person with Persistable, Observable {
@bindable
String name;
}
FIND TAGS USING
REFLECTION
ASYNC
Futures: I promise you a value
api.getCurrentUser()
.then((user) => api.loadUserProjects(user.id))
.then((projects) => api.loadProject(projects.first.id))
.then((project) => showProject(project))
.catchError((error) => printError(error));
Slide 44
Slide 44 text
ASYNC
Streams: A series of async events
• Clicks from a button
• DOM events
• Rows loaded from a database
• Bytes from a file
Slide 45
Slide 45 text
ASYNC
Streams: A series of async events
document.onKeyPress
.takeWhile((event) => event.keyCode != 13)
.map((event) => new String.fromCharCode(event.keyCode))
.toList() // Returns a Future of characters
.then((keys) => print(keys.join(",")));
Slide 46
Slide 46 text
HTML
Out of the box jQuery-esque APIs
Slide 47
Slide 47 text
HTML
Event listeners are Streams
document.onClick.listen((event) => print(event.client));
document.onKeyPress.listen((event) => print(event.keyCode));
Slide 48
Slide 48 text
HTML
Querying Elements
elem.querySelector('#foo');
elem.querySelector('.foo');
elem.querySelector('div');
elem.querySelectorAll('#foo');
elem.querySelectorAll('.foo');
elem.querySelectorAll('div');
Single Element Element List