All language subtitles for 9. [Dart] Functions as First Order Objects

af Afrikaans
ak Akan
sq Albanian
am Amharic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

0 Now in the last lesson, we vastly simplified and refactored our code. 1

And now it looks a lot simpler and a lot easier to read. 2

But there's just one thing. We know that we're currently using a reusableCard to be able to create a 3

card that has a particular margin or a particular look or a particular rounded border. 4

But we're also adding it as a child to a gesture detector to be able to detect when the user taps on 5

that card, and when that happens we set the selectedGender. 6

Now it's really likely that for other reusable cards, we might also want this functionality, being able 7

to detect touch. 8

And even if we don't need to, there's still two areas where we are repeating the same code right? 9

Adding a gesture detector to the reusableCard. 10

So why don't we just bite the bullet and upgrade our reusableCard to also be able to detect touch? 11

And that's what we're going to do in this lesson. And in the process, 12

I'm going to show you something really cool that you can do with Dart which is passing around functions 13

as if they were just any other object. 14

And I've just noticed that I've actually got a typo in the name of my file. 15

Over here you can see that I've written imput instead of input, but this is really easy to fix because 16

it's not affecting any of our code. 17

So if you ever get a typo or a spelling mistake in your file name, simply just right click on it and 18

click on refactor, rename and it will change all the places where this is used. So let's change that input 19

it will search for references, 20

search for comments and strings and it'll refactor everything to the right spelling. In Dart,functions 21

are first class citizens. 22

This means that they have a type and they can be passed around just like any other type 23

for example a string or an int. And they can also be set as the value of a variable or a constant. 24

So let's take a look at this now. 25

So here in my DartPad, I've got two functions. 26

One is a function called add which simply as the two numbers that it's given. 27

And the second one is called 28

multiply and it multiplies the two numbers that it's given. 29

Now if I wanted to perform a calculation, I could say add and then provide my numbers 3 and 5 30

for example, and then I would end up with a result. 31

So let's call it a int result equals the result of the add and then we'll print the result to the console. 32

And you can see that I will be able to run it as it is. 33

But what if I wanted to build a calculator where the user is able to tap on the plus button or the minus 34

button and perform the calculation that they need? 35

Well what if instead of having to call a different function each time instead, 36

what if I create a new function that returns an int and it's called calculator and it not only takes 37

two numbers int n1 and int n2, but it can also take a function as an argument? 38

So we would be able to add it as a type. 39

So for a string it would be string for an int it would be an int. But for function we would just write the 40

name Function with a capital F. And we could give it a name 41

let's call it calculation. 42

And then inside the body of the function, I will perform the calculation on those two numbers n1 and 43

n2. And then I would return the result of this calculation as the output of my calculator. 44

Now what I'm able to do is instead of having to call add then multiply then whatever, then in this case 45

I could simply write the result is going to be calculator performing a function on two numbers, let's 46

call it 5 and 8, and then the third input here is a function. 47

It's expecting an actual function as an input. 48

So I'm simply going to add the name. 49

So for example, add. Well in this case, it's clear that I want my calculator to perform some sort of function 50

on 5 and 8 and then add them together. 51

So now if I hit run you can see that it's going to try and add 5 and 8 together. 52

But if I simply switch out the parameter here into multiply, as long as I spell it right, then it will 53

multiply 5 and 8 together. 54

So functions are being passed around just as any other types, so if it was an int or if it was a string. 55

And this gives us a lot of flexibility and it's really powerful as we'll come to see. Now 56

the other thing that we can do with functions is we can even assign a function as the value of a variable. 57

So for example instead of saying int calculator, I could simply create a new variable that is of type 58

Function and I could call it calculator and I will set it to equal my function here. And at the very 59

end, I just have to cap it off with a semicolon. 60

So now it works exactly the same way as before. 61

If I click run and I change it to add or multiply, doesn't really matter, it still works as is. My function 62

is now stored inside a variable called calculator and I could even make this a final variable if I wished 63

to. 64

Which means that I'm no longer able to change the assignment of my calculator so I can't say calculator 65

now equals a different function for example. It'll give me an error telling me that calculator is a final 66

variable and can only be set once. 67

Now notice how at the moment, I'm creating functions completely outside of any classes and even outside 68

of the main function. 69

And this is perfectly legal in Dart. 70

You can have top level functions just like this and they are not associated with any class or object. 71

But let's see how it works inside a class. 72

So I'm going to delete all the code so far and I'm going to create a new class called Car. And car is 73

going to have a property that is a function and it's going to be called drive. 74

Now this property will be initialized when car gets constructed. 75

So I'm going to create my car constructor and I'm going to write this.drive to say that when I construct 76

my car, I have to provide a drive method to associate it with my car object. 77

Let's say that we have two modes of driving right? Let's create one which is called slowDrive, and in 78

this case it's simply going to print 'driving slowly'. 79

And then let's say we have another one which is called fast drive 80

and in this case it will print 'driving super fast.' 81

All right. 82

So now I have two functions which are top level functions. They are not associated with any class. But when 83

I initialize my car in my main function, for example I could say myCar is equal to a new car which 84

is constructed from the Car class. 85

And I now have to provide a value for the drive property. 86

So the drive property is going to be set equal a function 87

right? 88

So it's expecting a function. 89

I can't just put in a number, say 2 or I can't put in a string because it needs to be of the type function. 90

So let's give it a function because we have to. We can either say slowDrive or fastDrive. 91

Well let's say that my car starts out being a slowDrive car. 92

And notice how I'm not actually adding any parentheses after the function. 93

I'm simply passing over the name of that function. 94

So now at this stage myCar.drive is associated with the slowDrive function. 95

So I could show you this by simply running print myCar.drive. 96

And notice again I'm not putting a set of parentheses after drive because that is the thing that will 97

activate the function. 98

So right now if I print, you'll notice it'll print Closure 'slowDive'. 99

So that's pointing to this particular function. 100

It's saying that in myCar the drive property is equal to slowDrive. 101

But if I actually wanted to call my drive method, I would say myCar.drive. 102

And I would add the parentheses and any inputs if necessary. 103

And it's this line that actually triggers the drive method that is associated with my car. 104

And we're getting driving slowly printed to the console. 105

Now let's say that I wanted to upgrade my car right? 106

I will say myCar 107

.drive, the drive property is now going to be equal to fastDrive. 108

And again no parentheses after the method. 109

But I'm simply changing the value of that drive property on myCar. 110

So now I've taken my car to the garage. 111

It's being souped up. Now it's going to turbo and it's supercharged and it's blazing. 112

So now when I write myCar.drive and we print out the result. 113

So I'm going to comment out that line. 114

And now you can see that myCar's been upgraded and now it's driving super fast. When I'm passing functions 115

around, I'm just using its name. 116

I'm not adding the parentheses. 117

And when I want to call the method and actually trigger the functionality that's when I add the parentheses 118

and any inputs if necessary. Now that we've seen how flexible functions can be and how they can be passed 119

around just like any other object or any other type, 120

it's time for your challenge to apply what you've learned to our code. 121

The goal of the challenge is to do the gesturedetector on the first icon card and also the second 122

one and refactor it into the reusableCard 123

.dart file. So that way we can actually pass a function into our reusableCard just as we've passed 124

a color property or a cardChild and our function is also going to be passed as a value for one of these 125

properties. 126

So if you're successful by the end nothing about your app will have changed other than the fact that 127

the gesture detector should now live in the reusableCard and inside this build method. 128

Pause the video and see if you can solve this challenge. All right. 129

So first things first. I'm going to simply delete my gesture detector from this page. So I'm going to 130

hold down OPTION or ALT, hit ENTERand I'm going to remove my widget from both places. 131

So both in the first card and the second card. 132

Now I just have a pure reusableCard and I'm going to pass over the functionality where I set state 133

and change the selectedGender when the user clicks on this card or this card into my reusableCard. 134

So inside here in the build method, instead of just returning a container, I'm actually going to wrap 135

the container inside a gesture detector. 136

And here of course I will now again have access to the onTap. And I'm going to pass over a function 137

into my reusableCard widget. 138

So in exactly the same way that we did with our previous two properties, color and cardChild, I'm going 139

to add another final property which is going to have a function as the type. 140

And I'm going to call it onPress. And this is also going to be initialized when I create a new reusable 141

Card. 142

So I'm going to add the this.onPress over here so that I can pass over whichever function I want 143

to be used inside my reusableCard. 144

And then it's going to be set as the value of the onTap. 145

So this means that when I create a reusableCard, I can specify a function that is going to be the function 146

that will be called when the gesture detector detects a tap on the reusableCard. 147

So now I can go back to my input page and add some properties to my reusableCard. So I can add my on 148

Press which I just defined just now, 149

and it's going to be the same as what we would have done with the gesture detector. 150

We're going to add an anonymous function and inside the anonymous function, we have our set state and 151

inside the set state, 152

we change the selectedGender to gender.male in the first reusableCard and in our second reusable 153

card, 154

we have our onPress and in this case the set state is going to change the selectedGender to female. Now 155

when I hit save on my code, nothing about my app will change. You can see that it still works exactly 156

the same way as it did before, but now we've simply refactored the ability for our reusableCard, 157

this custom widget that we've built based on gesture detector, based on containers, based on box decorations 158

etc. and it's now also able to take a onPress. So it's able to respond to taps. 159

So we've essentially upgraded our reusableCard to also be able to detect touch simply by passing 160

over a function as the value of the onPress property. And the result of this is cleaner code with less 161

things being embedded and all the functionality and the design is now together in one widget. 162

It's always good practice to refactor your code as you go along. 163

This way you don't end up with spaghetti code at the end and lose all motivation to tidy it up. 164

You know that when your room gets to a certain state where it's just no longer possible to recover it 165

and then you give up. 166

That's not what we want with our code. 167

We want it to be neat and tidy and performance. 168

Now in the next lesson, we're going to continue working on the other cards that we have in our user interface. 169

And we're going to implement a Flutter slider to be able to select the user's height on a scale. 170

So for all of that and more, I'll see on the next lesson.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.