Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Object Literals & Optional Args

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $12.00

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!

Object Keys... without the Key

Start in _saveRepLog. Right now, we're passing $.ajax() some options: url, method and data:

'use strict';
(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:

'use strict';
(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:

'use strict';
(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:

'use strict';
(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.

Short Method Syntax

Next, you can do something similar with methods inside an object. The loadRepLogs() method is just a loadRepLogs key assigned to a function:

'use strict';
(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():

'use strict';
(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:

'use strict';
(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:

'use strict';
(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!

Optional Args

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:

'use strict';
(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():

'use strict';
(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":

'use strict';
(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:

'use strict';
(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:

'use strict';
(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!

'use strict';
(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.

Leave a comment!

0
Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial uses Symfony 3. But, since this is a JavaScript tutorial, all the concepts work fine in newer versions of Symfony.

What PHP libraries does this tutorial use?

// 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
    }
}
userVoice