If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
When it comes to functions and arrays, ES2015 has a couple of things you are going to love! Well, some of this stuff might look weird at first... but then you will love them!
Start in _saveRepLog
. Right now, we're passing $.ajax()
some options: url
, method
and data
:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 106 | |
_saveRepLog: function(data) { | |
return new Promise((resolve, reject) => { | |
$.ajax({ | |
url: Routing.generate('rep_log_new'), | |
method: 'POST', | |
data: JSON.stringify(data) | |
}).then((data, textStatus, jqXHR) => { | |
... lines 114 - 123 | |
}); | |
}); | |
}, | |
... lines 127 - 168 | |
}); | |
... lines 170 - 186 | |
})(window, jQuery, Routing, swal); |
Above that line, create a new url
variable set to the URL:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 106 | |
_saveRepLog: function(data) { | |
return new Promise((resolve, reject) => { | |
const url = Routing.generate('rep_log_new'); | |
$.ajax({ | |
... lines 112 - 125 | |
}); | |
}); | |
}, | |
... lines 129 - 170 | |
}); | |
... lines 172 - 188 | |
})(window, jQuery, Routing, swal); |
Then, use that below:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 106 | |
_saveRepLog: function(data) { | |
return new Promise((resolve, reject) => { | |
const url = Routing.generate('rep_log_new'); | |
$.ajax({ | |
url: url, | |
method: 'POST', | |
data: JSON.stringify(data) | |
}).then((data, textStatus, jqXHR) => { | |
... lines 116 - 125 | |
}); | |
}); | |
}, | |
... lines 129 - 170 | |
}); | |
... lines 172 - 188 | |
})(window, jQuery, Routing, swal); |
Obviously, this will work exactly like before: nothing interesting yet. Well, in ES2015, if your key and your value are the same, you can just leave off the key:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 106 | |
_saveRepLog: function(data) { | |
return new Promise((resolve, reject) => { | |
const url = Routing.generate('rep_log_new'); | |
$.ajax({ | |
url, | |
method: 'POST', | |
data: JSON.stringify(data) | |
}).then((data, textStatus, jqXHR) => { | |
... lines 116 - 125 | |
}); | |
}); | |
}, | |
... lines 129 - 170 | |
}); | |
... lines 172 - 188 | |
})(window, jQuery, Routing, swal); |
Yep, this means the same thing as before. So if you suddenly see an associative array or object where one of its keys is missing... well, it is the key... and the value.
Next, you can do something similar with methods inside an object. The loadRepLogs()
method is just a loadRepLogs
key assigned to a function:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 31 | |
loadRepLogs: function() { | |
... lines 33 - 39 | |
}, | |
... lines 41 - 170 | |
}); | |
... lines 172 - 188 | |
})(window, jQuery, Routing, swal); |
Simple, but too much work, maybe? In ES2015, we can shorten this to loadRepLogs()
:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 31 | |
loadRepLogs() { | |
... lines 33 - 39 | |
}, | |
... lines 41 - 170 | |
}); | |
... lines 172 - 188 | |
})(window, jQuery, Routing, swal); |
So much cooler! Let's change it everywhere! Search for the word function
, because
almost everything is about to change:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 31 | |
loadRepLogs() { | |
... lines 33 - 39 | |
}, | |
updateTotalWeightLifted() { | |
... lines 43 - 45 | |
}, | |
handleRepLogDelete(e) { | |
... lines 49 - 61 | |
}, | |
_deleteRepLog($link) { | |
... lines 65 - 82 | |
}, | |
handleRowClick() { | |
... line 86 | |
}, | |
handleNewFormSubmit(e) { | |
... lines 90 - 104 | |
}, | |
_saveRepLog(data) { | |
... lines 108 - 127 | |
}, | |
_mapErrorsToForm(errorData) { | |
... lines 131 - 146 | |
}, | |
_removeFormErrors() { | |
... lines 150 - 152 | |
}, | |
_clearForm() { | |
... lines 156 - 159 | |
}, | |
_addRow(repLog) { | |
... lines 163 - 169 | |
} | |
}); | |
... lines 172 - 178 | |
$.extend(Helper.prototype, { | |
calculateTotalWeight() { | |
... lines 181 - 186 | |
}, | |
... lines 188 - 191 | |
}); | |
})(window, jQuery, Routing, swal); |
Ultimately, the only function keywords that will be left are for the self-executing function - which could be an arrow function - and the two constructors:
; | |
(function(window, $, Routing, swal) { | |
window.RepLogApp = function ($wrapper) { | |
... lines 5 - 24 | |
}; | |
... lines 26 - 175 | |
const Helper = function ($wrapper) { | |
this.$wrapper = $wrapper; | |
}; | |
... lines 179 - 192 | |
})(window, jQuery, Routing, swal); |
Nice!
Ready for one more cool thing? This one is easy. Suppose we have a new method, not
calculateTotalWeight()
, but getTotalWeightString()
. Use the new shorthand syntax
and return this.calculateTotalWeight()
and append "pounds" to it:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 178 | |
$.extend(Helper.prototype, { | |
... lines 180 - 188 | |
getTotalWeightString() { | |
return this.calculateTotalWeight() + ' lbs'; | |
} | |
}); | |
})(window, jQuery, Routing, swal); |
Perfect! Then above, in updateTotalWeightLifted()
, instead of calling calculateTotalWeight()
and passing that to .html()
, pass getTotalWeightString()
:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 41 | |
updateTotalWeightLifted() { | |
this.$wrapper.find('.js-total-weight').html( | |
this.helper.getTotalWeightString() | |
); | |
}, | |
... lines 47 - 170 | |
}); | |
... lines 172 - 192 | |
})(window, jQuery, Routing, swal); |
Ok, nothing too crazy so far: when we refresh, at the bottom, yep, "pounds".
But now suppose that we want to set a max weight on that. What I mean is, if we are over a certain weight - maybe 500 - instead of printing the actual total, we want to print "500+"
Start by adding a new argument called maxWeight
. Then say let weight = this.calculateTotalWeight()
.
And if weight > maxWeight
, add weight = maxWeight + '+'
. At the bottom, return
weight
and "pounds":
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 178 | |
$.extend(Helper.prototype, { | |
... lines 180 - 188 | |
getTotalWeightString(maxWeight) { | |
let weight = this.calculateTotalWeight(); | |
if (weight > maxWeight) { | |
weight = maxWeight + '+'; | |
} | |
return weight + ' lbs'; | |
} | |
}); | |
})(window, jQuery, Routing, swal); |
Head up top to try this: when we call getTotalWeightString()
, pass 500:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 41 | |
updateTotalWeightLifted() { | |
this.$wrapper.find('.js-total-weight').html( | |
this.helper.getTotalWeightString(500) | |
); | |
}, | |
... lines 47 - 170 | |
}); | |
... lines 172 - 198 | |
})(window, jQuery, Routing, swal); |
Refresh! It works! We see the 500+ at the bottom.
But what if I wanted to make this argument optional with a default value of 500?
You could do this before in JavaScript, but it was ugly. Now, thanks to our new
best friend ES2015, we can say maxWeight = 500
- the same way we do in PHP:
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 178 | |
$.extend(Helper.prototype, { | |
... lines 180 - 188 | |
getTotalWeightString(maxWeight = 500) { | |
... lines 190 - 196 | |
} | |
}); | |
})(window, jQuery, Routing, swal); |
Now, we can remove the argument and everything is still happy!
; | |
(function(window, $, Routing, swal) { | |
... lines 4 - 26 | |
$.extend(window.RepLogApp.prototype, { | |
... lines 28 - 41 | |
updateTotalWeightLifted() { | |
this.$wrapper.find('.js-total-weight').html( | |
this.helper.getTotalWeightString() | |
); | |
}, | |
... lines 47 - 170 | |
}); | |
... lines 172 - 198 | |
})(window, jQuery, Routing, swal); |
So, yay! Finally, JavaScript has optional function arguments! And a second yay, because we are ready to learn perhaps the biggest change in ES2015: JavaScript classes.
"Houston: no signs of life"
Start the conversation!
// composer.json
{
"require": {
"php": "^7.2.0",
"symfony/symfony": "3.2.*", // v3.2.14
"twig/twig": "2.10.*", // v2.10.0
"doctrine/orm": "^2.5", // v2.7.1
"doctrine/doctrine-bundle": "^1.6", // 1.10.3
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.2
"symfony/swiftmailer-bundle": "^2.3", // v2.4.2
"symfony/monolog-bundle": "^2.8", // v2.12.1
"symfony/polyfill-apcu": "^1.0", // v1.3.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.19
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"friendsofsymfony/user-bundle": "~2.0@dev", // dev-master
"doctrine/doctrine-fixtures-bundle": "~2.3", // v2.4.1
"doctrine/doctrine-migrations-bundle": "^1.2", // v1.2.1
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"friendsofsymfony/jsrouting-bundle": "^1.6" // 1.6.0
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.2
"symfony/phpunit-bridge": "^3.0" // v3.2.2
}
}