Buy Access to Course
07.

Object Literals & Optional Args

Share this awesome video!

|

Keep on Learning!

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:

188 lines | web/assets/js/RepLogApp.js
'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:

190 lines | web/assets/js/RepLogApp.js
'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:

190 lines | web/assets/js/RepLogApp.js
'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:

190 lines | web/assets/js/RepLogApp.js
'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:

190 lines | web/assets/js/RepLogApp.js
'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():

190 lines | web/assets/js/RepLogApp.js
'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:

194 lines | web/assets/js/RepLogApp.js
'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:

194 lines | web/assets/js/RepLogApp.js
'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:

194 lines | web/assets/js/RepLogApp.js
'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():

194 lines | web/assets/js/RepLogApp.js
'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":

200 lines | web/assets/js/RepLogApp.js
'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:

200 lines | web/assets/js/RepLogApp.js
'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:

200 lines | web/assets/js/RepLogApp.js
'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!

200 lines | web/assets/js/RepLogApp.js
'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.