Trapped in ES5

One of the platforms that I develop and maintain for my current employer is the LG SmartTV App, and the oldest TV version we support is the LG TV with webOS 3.5. Most of the TVs with this OS were released in 2017, but the OS itself is based on Chromium 38, which was released in August 2014, around three years earlier.
Everything is fine since we transpile our code into ES5 using Babel. However, when I needed to update the legacy scripts inside index.html that were not transpiled, something surprised me.
I added a default parameter to a JavaScript function, but it made the app unable to run on that webOS version. I realized that a default parameter is part of ES6 and was only available since Chromium 49. Luckily, we managed to fix that before it was released to production.
It’s funny; I thought that feature had already been available for a long time, but apparently, the OS couldn’t handle it. As a programmer who has been coding JavaScript before the ES6 existence, I had already forgotten the excitement when welcoming the ES6 features, so I thought it was released a decade ago. Thanks to caniuse.com, we can always check the browser/engine support.
Ngelanturin Minat Baca
Kalian suka kangen enggak si, dengan memori ketika kalian enggak punya agenda lain selain baca komik Doraemon yang baru dibeli dari Gramedia di siang harinya. Dibaca setiap halaman dengan pelan, dinikmati setiap gambarnya, sambil berimajinasi apa yang sedang terjadi dengan Nobita di Jepang sana.
Trus kalian nemu satu halaman yang cukup relate. Seperti ketika mereka membahas tentang Ensiklopedi, dan kalian punya ensiklopedi sendiri di rumah.

Trus kalian berhenti sejenak dari baca komik, untuk coba liat ada apa aja di ensiklopedi. Buka halaman secara acak dan menemukan kalimat yang belum pernah kalian tau, beserta penjelasannya.
Dulu gue punya banyak komik, dari Doraemon sampe Dragon Ball, komplit. Komik – komik itu yang mungkin membuat gue waktu kecil jadi rajin baca. Mulai dari baca ensiklopedi hingga biografi Presiden Suharto.
Tapi entah kenapa gue ngerasa minat baca gue sekarang berkurang. Gue lebih suka nonton tutorial berupa video ketimbang baca tutorial berformat teks secara runut. Kalaupun gue mencari suatu informasi dan ketemu artiket yang berkaitan, gue cenderung untuk hanya mencari informasi yang gue butuhkan di artiket tersebut, tanpa baca secara hati-hati dari kalimat pertama. Dan kadang itu membuat gue kehilangan konteks dari artikel yang gue temukan.
Gue ngerasa gue selalu dikejar waktu. Sehingga informasi yang gue butuhkan harus didapat secepat mungkin, tanpa mempelajari hal lain yang mungkin berkaitan dengan informasi tersebut. Padahal kalo ngomongin waktu, gue cukup rajin buka twitter atau scroll instagram, dan itu justru lebih membuang waktu.
Sampe sekarang gue belum menemukan teknik yang manjur buat mengurangi kebiasaan itu. Yang bisa gue lakukan sekarang adalah cek screen time
di iphone untuk lihat persentase aplikasi yang gue buka. Antara Social Networking, Productivity, atau Entertainment. Selama ini Social Networking masih merajai, namun berprogress meskipun lambat berkurang. Semoga gak kecanduan sosmed lagi.
Generator Bilangan Prima
Ini hanyalah contoh tambahan dari tulisan yang gue tulis sebelumnya disini https://afief.net/iterables-iterator-generator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function * primeNumbers (count = 10) { const numbers = [] let current = 2 const isPrime = (num) => !numbers.find(v => Number.isInteger(num / v)) while (true) { if (count <= 0) break if (isPrime(current)) { numbers.push(current) yield current count-- } current++ } } |
Untuk membuat 15 bilangan prima, cukup dengan
1 2 |
[...primeNumbers(15)] // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] |
Iterables, iterator, dan generator function
Ribuan programmer mungkin tidak menyadari bahwa Array di Javascript bukanlah Array yang seutuhnya tanpa Symbol.iterator. Misal, kita punya array
1 |
const fibo = [1, 1, 2, 3, 5, 8, 13, 21] |
Lalu, dengan for...of...
, kita akan lihat value dari variable tersebut satu per satu.
1 2 |
for (let v of fibo) console.log(v) // 1 1 2 3 5 8 13 21 |
Nilai dari variable tersebut ditampilkan sesuai ekspektasi. Hal itu bisa terjadi karena Array yang kita kenal merupakan iterables
. Iterables
memiliki fungsi yang membuat nilai-nilai di data tersebut dapat dilihat secara berurutan. Bisa dengan menggunakan statemen for...of...
, bisa juga dengan spread operator (...)
.
Salah satu ciri dari iterables adalah memuat property [Symbol.iterator]
yang merupakan function
. Secara default property tersebut ada di variable yang memuat Array, String, Set, Map, atau TypedArray. Nah, apa yang terjadi kalau kita ubah Symbol.iterator
di itarables menjadi bukan function?
1 2 3 4 |
fibo[Symbol.iterator] = '' for (let v of fibo) console.log(v) // TypeError: fibo is not iterable |
Statement diatas akan melempar error karena for...of...
membutuhkan dan memanggil iterable property—Symbol.iterator—agar mendapatkan iterator
yang berfungsi untuk mengatur nilai-nilai yang akan diberikan ke variable v
.
Membuat Non-Iterable Object menjadi Iterable
Untuk membuat object biasa menjadi iterable, kita perlu menambahkan Symbol.iterator
ke dalam object tersebut. Symbol.iterator
harus berupa function yang mengembalikan iterator. Iterator
harus memuat function next()
yang akan dipanggil beberapa kali dan mengatur nilai yang akan dikeluarkan setiap pemanggilan function tersebut.
Misal, kita mempunyai object berupa data member yang dikelompokkan berdasarkan ranking.
1 2 3 4 5 6 7 8 9 10 11 12 |
const members = { beginner: [ { name: 'John', retired: true }, { name: 'Lucas'}, { name: 'Doni'} ], advance: [ { name: 'Toni' }, { name: 'Jessica', retired: true }, { name: 'Angelia' } ] } |
Lalu kita perlu membuat object tersebut menjadi iterables agar kita dapat menggunakan Spread Operator
untuk membuat array yang berisi semua member yang belum retired. Maka, kita bisa menambahkan Symbol.iterator
ke dalam object tersebut sebagai berikut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
members[Symbol.iterator] = function () { const usersByRanks = Object.values(this) let rankIndex = 0 let userIndex = 0 return { next() { if (userIndex >= usersByRanks[rankIndex].length) { rankIndex++ userIndex = 0 } if (rankIndex >= usersByRanks.length) { return { done: true } } if (usersByRanks[rankIndex][userIndex].retired) { userIndex++ return this.next() } return { done: false, value: usersByRanks[rankIndex][userIndex++]} } } } |
Kini, setiap kali object members tersebut digunakan di for...of...
loop atau di spread operator
, variabel rankIndex
dan userIndex
di set menjadi 0 dan berfungsi sebagai “cursor” yang mengatur nilai mana yang akan dikeluarkan di setiap pemanggilan next().
1 2 |
console.log([...members]) // [ { name: 'Lucas' }, { name: 'Doni' }, { name: 'Toni' }, { name: 'Angelia' } ] |
Tanpa menggunakan spread operator
, kita juga bisa mengambil satu per satu nilai dari variable members
diatas dengan memanggil function next() melalui iteratornya.
1 2 3 4 5 6 7 |
const iterator = members[Symbol.iterator]() console.log(iterator.next()) // { done: false, value: { name: 'Lucas' } } console.log(iterator.next()) // { done: false, value: { name: 'Doni' } } console.log(iterator.next()) // { done: false, value: { name: 'Toni' } } |
Generator Function
Generator function adalah function yang menghasilkan iterator
. Ciri dari function ini adalah adanya tambahan asterik * pada setiap deklarasinya. Di generator function, kita juga menggunakan yield
untuk mengembalikan nilai yang dibutuhkan pada setiap iterasi. yield
hanya perlu mengembalikan nilai tanpa perlu menambahkan property done
.
Berikut contoh pernggunaan generator function menggantikan function iterator manual pada object member
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
members[Symbol.iterator] = function * () { const usersByRanks = Object.values(this) let rankIndex = 0 let userIndex = 0 while (true) { if (userIndex >= usersByRanks[rankIndex].length) { rankIndex++ userIndex = 0 } if (rankIndex >= usersByRanks.length) { break } if (usersByRanks[rankIndex][userIndex].retired) { userIndex++ continue } yield usersByRanks[rankIndex][userIndex++] // user } } |
Loop while
akan terus berputar sampai kondisi rankIndex >= usersByRanks.length
terpenuhi. Dan apabila kondisi usersByRanks[rankIndex][userIndex].retired
tidak terpenuhi, maka keyword yield
akan digunakan untuk mengeluarkan nilai user selanjutnya.
Selain membuat object menjadi iterables, generator function juga dapat digunakan secara mandiri untuk membuat sebuah iterator. Berikut adalah generator function yang menghasilkan iterator untuk bilangan fibonacci
1 2 3 4 5 6 7 8 9 10 11 12 |
function * fibo (maxCount = 1000) { let previous = 1 let initial = 0 while (maxCount-- > 0) { const nextValue = initial + previous yield nextValue previous = initial initial = nextValue } } console.log([...fibo(10)]) // [ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ] |
Generator function
diatas menerima satu argumen sebagai jumlah maksimal bilangan fibonacci yang akan dihasilkan.
Blog usang yang “hampir” terlupakan
Kemarin pagi, saat iseng cari nama lengkap sendiri di google, yang muncul di halaman pertama hanyalah beberapa sosial media dan tautan – tautan di website pemerintah dan kampus. Blog dan landing page dengan nama sendiri malah hanya ada di halaman kedua.
Tulisan terakhir di blog ini pun hampir dua tahun lalu. Sungguh sebagai seorang suami yang bertemu istrinya pertama kali di komunitas blogger kampus, ini adalah sebuah wanprestasi.
Blog yang—setelah gue coba kembali login—memunculkan banyak notifikasi update pun kembali gue ulik. Dan gue pun menemukan Block Editor.
Editor wordpress yang masih baru buat gue ini terlihat lebih bersih dari editor sebelumnya. Tak perlu enter dua kali untuk membuat paragraf baru. Cukup enter sekali akan terlihat perbedaan antar paragraf. Kita juga bisa ganti style setiap block di menu yang muncul di block tersebut.

Setiap block juga gampang untuk digeser ke atas maupun ke bawah. Ini berguna banget kalo kita mau sisipin gambar, lalu pindahin gambar itu ke atas / bawah paragraf tertentu.
Kira – kira, apalagi ya fitur di WordPress baru yang belum gue tau dan bikin semangat nulis lagi? 😅
Await loop over an object
I always rely on bluebird each / all to loop over an array. Until someday I meet the case where I need to use await loop over an object. Surprisingly, after trying on chrome inspector, for loop on object is very doable :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const delayed = (v) => { return new Promise((res) => { setTimeout(() => { res(v) }, 1000) }) } const test = async () => { const k = { a: 'Happy', b: 'New', c: 'Year!' } for (let i in k) { let text = await delayed(k[i]) console.log(text) } console.log('DONE!') } test () |
Above codes will print a text on variable k with delay every 1 second.
Bekraf Developer Conference

Minggu – Senin kemarin dateng ke salah satu acara dari Bekraf di Aston Simatupang Jakarta Selatan, Bekraf Developer Conference. Ini acara puncak dari rangkaian acara Bekraf Developer Day yang diadakan di beberapa kota sebelumnya.
Selayaknya sebuah konferensi, goal dari acaranya ini adalah merumuskan tantangan para developer dan solusi yang bisa disampaikan ke para pemangku kebijakan. Dari konferensi yang diadakan hingga jam 10 malam tsb, dirumuskan banyak tantangan dan solusi yang dapat kalian lihat disini.
Jadi Fasilitator di Indonesia Android Kejar

Google melalui Google Developers akhir tahun ini mengadakan Google Indonesia Android Kejar (page). Sebagai sarjana kurang ngajar dan developer yang pertengahan Oktober lalu sudah tidak di Inmotion lagi, gue gabung sebagai fasilitator.
Ini jadi pengalaman baru dan berbeda setelah sekian lama gak berada di depan kelas. Kalau di kesempatan lain diundang untuk mengisi workshop dengan kelas yang sudah disediakan, peserta yang jumlahnya sudah fix, dan amplop (ehem) yang jumlah isinya belum pasti namun bisa dipastikan ada isinya. Disini, setiap fasilitator mencari dan mengkoordinasi tempat untuk offline study group, menghubungi peserta untuk join di group whatsapp dan standby dengan problem mereka, serta sedari awal disebutkan rewardnya tidak disebutkan dalam mata uang.
Namun apa yang gue dapet disini jelas gak bisa dibandingkan dengan menjadi fasilitator di tempat lain pada tahun-tahun sebelumnya. Di program ini, gue yang lebih banyak bersentuhan dengan teknologi web, mau gak mau harus belajar Android Studio dengan java-nya yang amat kental. Dengan begitu, motifasi gue sejak tahun 2011 belajar development native android sedikit dipaksakan dan itu bener-bener berhasil bikin gue fasih dan pede untuk lebih dalem di development native android.
Sebelumnya, gue lebih banyak membuat dan mempublish aplikasi mobile dengan Ionic Framework ke playstore. Hanya ada satu aplikasi yang gue develop dengan Android Studio, aplikasi untuk event Google MakeTimeFly (contoh hasilnya) yang di develop selama dua minggu. Sebenernya gue cukup puas dengan aplikasi itu, namun karna waktu development yang cukup singkat, gak banyak konsep dasar yang gue pelajari.
My Spotify Playlist

Satu lagi yang menarik dari Spotify, Recomended Songs. Ketika membuat playlist, di bagian bawah daftar lagu playlist itu bakalan ada daftar lagu yang setipe. Gak jarang lagu-lagu itu juga asik dan cocok. Salah satu playlistnya yang gue buat disini
Playlist Kamis : Short Change Hero

Playlist Kamis minggu ini gue pilih Theme-Songnya Borderlands 2, Short Change Hero. Short Change Hero ada pada album The House That Dirt Built yang di release oleh Band Indie Rock asal Inggris, The Heavy. The Heavy sendiri merelease album pertamanya Tahun 2007 dengan genre Neo Soul.
Selain digunakan di Borderlands 2, Short Change Hero juga ada di trailernya Batman: Arkham City dan TV Serial Suits.