[{"data":1,"prerenderedAt":2453},["ShallowReactive",2],{"i-mdi:github":3,"i-mdi:linkedin":8,"i-mdi:instagram":10,"blog":12,"i-solar:calendar-linear":2449,"i-solar:round-arrow-right-linear":2451},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"currentColor\" d=\"M19 3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2zm-.5 15.5v-5.3a3.26 3.26 0 0 0-3.26-3.26c-.85 0-1.84.52-2.32 1.3v-1.11h-2.79v8.37h2.79v-4.93c0-.77.62-1.4 1.39-1.4a1.4 1.4 0 0 1 1.4 1.4v4.93zM6.88 8.56a1.68 1.68 0 0 0 1.68-1.68c0-.93-.75-1.69-1.68-1.69a1.69 1.69 0 0 0-1.69 1.69c0 .93.76 1.68 1.69 1.68m1.39 9.94v-8.37H5.5v8.37z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cpath fill=\"currentColor\" d=\"M7.8 2h8.4C19.4 2 22 4.6 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8C4.6 22 2 19.4 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2m-.2 2A3.6 3.6 0 0 0 4 7.6v8.8C4 18.39 5.61 20 7.6 20h8.8a3.6 3.6 0 0 0 3.6-3.6V7.6C20 5.61 18.39 4 16.4 4zm9.65 1.5a1.25 1.25 0 0 1 1.25 1.25A1.25 1.25 0 0 1 17.25 8A1.25 1.25 0 0 1 16 6.75a1.25 1.25 0 0 1 1.25-1.25M12 7a5 5 0 0 1 5 5a5 5 0 0 1-5 5a5 5 0 0 1-5-5a5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3\"\u002F>",[13,283,417,567,685,1110,2226],{"id":14,"title":15,"body":16,"date":272,"description":273,"extension":274,"image":275,"meta":276,"navigation":277,"path":278,"seo":279,"sitemap":280,"stem":281,"__hash__":282},"blog\u002Fblog\u002Fwhy-nuxt.md","Why using Nuxt.js?",{"type":17,"value":18,"toc":241},"minimark",[19,24,33,36,39,43,46,49,52,55,59,62,65,68,71,81,85,88,97,104,111,114,121,124,131,134,141,144,151,154,161,164,171,174,178,181,184,188,191,194,197,200,204,207,210,213,216,220,223,227,230,233,236],[20,21,23],"h2",{"id":22},"the-moment-we-realized-our-was-growing-up","The Moment We Realized Our 👶 Was Growing Up",[25,26,27,28,32],"p",{},"Picture this: It's another late evening in our office, and I'm staring at a codebase that once felt like home. Our dashboard—",[29,30,31],"em",{},"our baby","—the one we've nurtured since the very first day this company came to life, was starting to show its age.",[25,34,35],{},"You know that feeling when you realize your childhood home feels smaller than you remember? That's exactly how we felt about our jQuery and vanilla JavaScript foundation. What once felt magical and limitless now felt... constrained.",[25,37,38],{},"Our team was growing faster than we ever imagined. New features were rolling out almost monthly, and with each release, I could see the strain in my teammates' eyes. The late-night debugging sessions were getting longer, the \"quick fixes\" were taking hours, and worst of all—that spark of joy we once had while coding was slowly dimming.",[20,40,42],{"id":41},"the-weight-of-legacy","The Weight of Legacy",[25,44,45],{},"I'll be honest with you—admitting that our legacy dashboard was holding us back was one of the hardest professional moments I've faced. This wasn't just code; it was our identity, our foundation, our proof that we could build something meaningful from scratch.",[25,47,48],{},"But love sometimes means letting go, right?",[25,50,51],{},"The jQuery and vanilla JavaScript that had served us so well were now becoming roadblocks. Every new team member needed weeks just to understand our custom patterns. Every modern library integration felt like forcing a square peg into a round hole. We were spending more time fighting our tools than creating value for our users.",[25,53,54],{},"And our users... they deserved better. They deserved the fast, smooth, delightful experience that modern web technologies could provide.",[20,56,58],{"id":57},"the-search-for-our-new-foundation","The Search for Our New Foundation",[25,60,61],{},"What followed was probably the most intense research phase of our careers. This wasn't just about picking a framework—this was about choosing the future of our company, our team's happiness, and our users' experience.",[25,63,64],{},"We dove deep into the trenches of React, Angular, and Vue.js. I remember the countless nights scrolling through documentation, watching tutorials, and having heated (but loving) debates with my team about the pros and cons of each approach.",[25,66,67],{},"The meta-frameworks were our next challenge: Next.js, Nuxt.js, Angular Universal, and even SvelteKit. Each had its own personality, its own promises, its own learning curve.",[25,69,70],{},"This was before the ChatGPT era, so every piece of knowledge was hard-earned through blog posts, Stack Overflow deep-dives, and GitHub issue discussions. We were digital archaeologists, uncovering the truth about each technology through real-world experiences shared by developers around the globe.",[25,72,73,74,80],{},"After weeks of research that felt like months, something clicked when we experimented with Nuxt.js for our help page at ",[75,76,77],"a",{"href":77,"rel":78},"https:\u002F\u002Fhelp.kiriminaja.com",[79],"nofollow",". The developer experience felt... right. It felt like coming home to a house that was both familiar and excitingly new.",[20,82,84],{"id":83},"why-nuxtjs-stole-our-hearts","Why Nuxt.js Stole Our Hearts",[25,86,87],{},"Here's why Nuxt.js didn't just win our minds—it won our hearts:",[89,90,92,93],"h3",{"id":91},"_1-vuejs-ecosystem-the-gentle-giant","1. ",[94,95,96],"strong",{},"Vue.js Ecosystem - The Gentle Giant",[25,98,99,100,103],{},"Vue felt like a breath of fresh air after years of complex abstractions. Its gentle learning curve meant our team could actually ",[29,101,102],{},"enjoy"," learning something new instead of drowning in documentation. The progressive nature of Vue allowed us to migrate piece by piece without throwing away everything we'd built.",[89,105,107,108],{"id":106},"_2-server-side-rendering-ssr-and-static-site-generation-ssg-performance-that-actually-matters","2. ",[94,109,110],{},"Server-Side Rendering (SSR) and Static Site Generation (SSG) - Performance That Actually Matters",[25,112,113],{},"Remember the satisfaction of seeing your users' faces light up when pages load instantly? That's what SSR gave us back. No more apologizing for slow load times or watching users abandon our app because of poor performance.",[89,115,117,118],{"id":116},"_3-modular-architecture-building-blocks-that-actually-work","3. ",[94,119,120],{},"Modular Architecture - Building Blocks That Actually Work",[25,122,123],{},"The module system felt like having a Swiss Army knife for web development. Need authentication? There's a module. Want to add PWA features? Another module. It was like having superpowers without the complexity.",[89,125,127,128],{"id":126},"_4-developer-experience-joy-in-coding-again","4. ",[94,129,130],{},"Developer Experience - Joy in Coding Again",[25,132,133],{},"Hot module replacement, intuitive file-based routing, auto-imports—these weren't just features; they were daily gifts that made coding fun again. I started looking forward to Monday mornings because working with Nuxt felt effortless.",[89,135,137,138],{"id":136},"_5-performance-optimization-speed-without-the-headache","5. ",[94,139,140],{},"Performance Optimization - Speed Without the Headache",[25,142,143],{},"Code splitting, lazy loading, and bundle optimization happened automatically. We went from performance optimization being a dreaded task to something that just... worked.",[89,145,147,148],{"id":146},"_6-strong-community-and-ecosystem-never-coding-alone","6. ",[94,149,150],{},"Strong Community and Ecosystem - Never Coding Alone",[25,152,153],{},"The Vue and Nuxt community felt like a warm hug compared to other ecosystems. When we had questions, we got helpful answers, not condescending lectures.",[89,155,157,158],{"id":156},"_7-typescript-support-safety-net-for-growing-teams","7. ",[94,159,160],{},"TypeScript Support - Safety Net for Growing Teams",[25,162,163],{},"As our team grew, TypeScript became our safety net. Nuxt's excellent TypeScript integration meant fewer late-night bug hunts and more confidence in our code.",[89,165,167,168],{"id":166},"_8-flexibility-and-versatility-one-tool-many-dreams","8. ",[94,169,170],{},"Flexibility and Versatility - One Tool, Many Dreams",[25,172,173],{},"Whether we needed a SPA, SSR, or static site, Nuxt adapted to our needs instead of forcing us to adapt to its constraints.",[20,175,177],{"id":176},"the-hardest-decision-letting-go","The Hardest Decision: Letting Go",[25,179,180],{},"After 2-3 months of falling in love with Nuxt.js, reality hit us like a truck. Our main dashboard—our monolithic masterpiece—was taking forever to build and deploy. Every small change felt like moving a mountain.",[25,182,183],{},"The decision to migrate our entire dashboard to Nuxt.js was probably the scariest professional choice we've ever made. This wasn't just changing a tool; this was acknowledging that our baby needed to grow up, and we needed to help it.",[20,185,187],{"id":186},"two-years-of-living-in-two-worlds","Two Years of Living in Two Worlds",[25,189,190],{},"What followed was the most challenging period of our careers. For almost two years, we lived in parallel universes—maintaining our legacy dashboard while building its future replacement.",[25,192,193],{},"Some nights, I questioned everything. Was this the right choice? Were we over-engineering? Were we solving the right problems?",[25,195,196],{},"But then I'd see a team member's face light up when they successfully implemented a complex feature in half the time it would have taken in the old system. Or when a user complimented our app's speed and responsiveness. Those moments reminded me why we started this journey.",[25,198,199],{},"The testing cycles felt endless. Develop, port, test, discover edge cases, fix, test again. Repeat. Each iteration brought us closer to something beautiful, but the path felt longer than we'd ever imagined.",[20,201,203],{"id":202},"september-2025-the-day-we-finally-let-go","September 2025: The Day We Finally Let Go",[25,205,206],{},"After what felt like a lifetime of preparation, September 2025 arrived—the day we officially launched our new Nuxt.js dashboard to all our users.",[25,208,209],{},"I still remember refreshing our monitoring dashboard, watching user sessions flow seamlessly through the new interface. No critical bugs, no performance issues, just happy users experiencing the modern, fast, delightful application we'd dreamed of building.",[25,211,212],{},"The first beta had launched way back in 2023, and seeing how far we'd come felt surreal. We didn't just migrate a codebase—we transformed our entire approach to building web applications.",[25,214,215],{},"Today, I'm proud to say that 80% of our new web frontend applications are built with Nuxt.js. It has become our go-to choice for almost every frontend project, proving that our initial leap of faith was absolutely worth it.",[20,217,219],{"id":218},"is-nuxtjs-perfect","Is Nuxt.js Perfect?",[25,221,222],{},"No it isn't. Every technology has its trade-offs, and Nuxt.js is no exception. There were moments of frustration, unexpected bugs, and learning curves that tested our patience. We also use some other frontend frameworks for specific projects where they make more sense like React Router for our Shopify app, but overall, the benefits far outweighed the challenges.",[20,224,226],{"id":225},"looking-back-with-gratitude","Looking Back With Gratitude",[25,228,229],{},"Today, when I see new developers joining our team and getting productive in days instead of weeks, I'm reminded that sometimes the hardest decisions lead to the most beautiful outcomes.",[25,231,232],{},"Our jQuery and vanilla JavaScript foundation wasn't a mistake—it was our beginning. Nuxt.js isn't just our present—it's the foundation for everything we'll build tomorrow.",[25,234,235],{},"If you're reading this and facing a similar decision, know that it's okay to feel scared. It's okay to question whether you're making the right choice. But also know that sometimes, the best way to honor what you've built is to help it become something even better.",[25,237,238],{},[29,239,240],{},"What's your migration story? I'd love to hear about your journey!",{"title":242,"searchDepth":243,"depth":243,"links":244},"",2,[245,246,247,248,267,268,269,270,271],{"id":22,"depth":243,"text":23},{"id":41,"depth":243,"text":42},{"id":57,"depth":243,"text":58},{"id":83,"depth":243,"text":84,"children":249},[250,253,255,257,259,261,263,265],{"id":91,"depth":251,"text":252},3,"1. Vue.js Ecosystem - The Gentle Giant",{"id":106,"depth":251,"text":254},"2. Server-Side Rendering (SSR) and Static Site Generation (SSG) - Performance That Actually Matters",{"id":116,"depth":251,"text":256},"3. Modular Architecture - Building Blocks That Actually Work",{"id":126,"depth":251,"text":258},"4. Developer Experience - Joy in Coding Again",{"id":136,"depth":251,"text":260},"5. Performance Optimization - Speed Without the Headache",{"id":146,"depth":251,"text":262},"6. Strong Community and Ecosystem - Never Coding Alone",{"id":156,"depth":251,"text":264},"7. TypeScript Support - Safety Net for Growing Teams",{"id":166,"depth":251,"text":266},"8. Flexibility and Versatility - One Tool, Many Dreams",{"id":176,"depth":243,"text":177},{"id":186,"depth":243,"text":187},{"id":202,"depth":243,"text":203},{"id":218,"depth":243,"text":219},{"id":225,"depth":243,"text":226},"2025-12-09","A heartfelt journey of how our team transformed from jQuery warriors to Nuxt.js advocates. This is the story of letting go of our legacy baby and embracing a future that scared and excited us at the same time.","md","\u002Fimages\u002Fblog\u002Fwhy-nuxt.webp",{},true,"\u002Fblog\u002Fwhy-nuxt",{"title":15,"description":273},{"loc":278},"blog\u002Fwhy-nuxt","NhbtZe_fGN_8v4fhAAXcxsamTH1WRMGtdD3TFgLW2EU",{"id":284,"title":285,"body":286,"date":408,"description":409,"extension":274,"image":410,"meta":411,"navigation":277,"path":412,"seo":413,"sitemap":414,"stem":415,"__hash__":416},"blog\u002Fblog\u002Fmy-new-domain.md","New Domain, New Chapter",{"type":17,"value":287,"toc":400},[288,292,307,311,317,321,338,342,345,367,371,389,392],[20,289,291],{"id":290},"a-fresh-start-with-yanad","A Fresh Start with yan.ad",[25,293,294,295,298,299,302,303,306],{},"If you’ve followed my journey, you might know I have a bit of a habit: changing my domain name! From ",[94,296,297],{},"yanuar.co"," to ",[94,300,301],{},"yanuar.dev"," and a few others in between, my online presence has always been evolving. But today, I’m excited to announce that ",[94,304,305],{},"yan.ad"," is here to stay as my professional portfolio page.",[89,308,310],{"id":309},"why-yanad","Why yan.ad?",[25,312,313,314,316],{},"I wanted a domain that’s short, memorable, and truly represents my personal brand. After experimenting with several options, ",[94,315,305],{}," felt like the perfect fit for my portfolio and future projects.",[89,318,320],{"id":319},"a-sad-news-why-not-yanuar-or-yanuarid","A Sad News: Why Not yanu.ar or yanuar.id?",[25,322,323,324,327,328,331,332,334,335,337],{},"Some of you might wonder why I didn’t go with ",[94,325,326],{},"yanu.ar"," or ",[94,329,330],{},"yanuar.id",". Unfortunately, ",[94,333,326],{}," is not only more expensive, but it’s also a bit harder to pronounce for Indonesian speakers. As for ",[94,336,330],{},", it’s sadly already taken by someone else out of nowhere. So, I decided to go with something that’s both practical and easy to remember.",[89,339,341],{"id":340},"built-with-modern-tools","Built with Modern Tools",[25,343,344],{},"This new site is crafted using the latest technologies:",[346,347,348,355,361],"ul",{},[349,350,351,354],"li",{},[94,352,353],{},"Nuxt.js 3"," for a fast, modern web experience",[349,356,357,360],{},[94,358,359],{},"Tailwind CSS"," for utility-first, responsive styling",[349,362,363,366],{},[94,364,365],{},"Material 3 Expressive Design"," for a clean, accessible, and visually appealing interface",[89,368,370],{"id":369},"professional-email-hosting","Professional Email & Hosting",[25,372,373,374,377,378,384,385,388],{},"To keep things professional, I’ve set up my email using ",[94,375,376],{},"Zoho Mail","—so you can always reach me at ",[94,379,380],{},[75,381,383],{"href":382},"mailto:me@yan.ad","me@yan.ad",". The site itself is hosted on ",[94,386,387],{},"Vercel",", ensuring fast load times and reliable uptime.",[25,390,391],{},"Thanks for joining me on this new chapter. Feel free to explore my portfolio, check out my projects, and get in touch!",[25,393,394,397,398],{},[94,395,396],{},"Contact:"," ",[75,399,383],{"href":382},{"title":242,"searchDepth":243,"depth":243,"links":401},[402],{"id":290,"depth":243,"text":291,"children":403},[404,405,406,407],{"id":309,"depth":251,"text":310},{"id":319,"depth":251,"text":320},{"id":340,"depth":251,"text":341},{"id":369,"depth":251,"text":370},"2025-06-01","A new domain, a new beginning. This blog post marks the start of my journey with a fresh domain and a renewed focus on sharing knowledge and experiences.","\u002Fimages\u002Fblog\u002Fnew-domain.png",{},"\u002Fblog\u002Fmy-new-domain",{"title":285,"description":409},{"loc":412},"blog\u002Fmy-new-domain","tIgGsTMnFgrWb6c98scElAq7oIPHXgqyq86Vc4jyWyo",{"id":418,"title":419,"body":420,"date":558,"description":559,"extension":274,"image":560,"meta":561,"navigation":277,"path":562,"seo":563,"sitemap":564,"stem":565,"__hash__":566},"blog\u002Fblog\u002Ftauri-app-si-calon-pesaing-electron-js-yang-ditulis-menggunakan-rust.md","Tauri: The Upcoming Electron Competitor Written in Rust",{"type":17,"value":421,"toc":553},[422,425,433,437,445,473,477,480,491,495],[25,423,424],{},"When talking about cross-platform desktop apps, we can't ignore popular names like electron.js and meteor.js. Electron is currently the most popular framework, with over 100k stars on GitHub, and we all know that electron.js is managed and developed by GitHub as the main contributor. However, before Tauri arrived, Electron was often criticized for using Chromium as its application renderer, which, as we know, is quite memory-hungry. So, how do we solve this? Well, you could use native code—just kidding. Is there another solution?",[25,426,427,428,432],{},"Yes, there is! It's called Tauri, a newcomer built using Rust as its compiler. Unlike Electron, which uses the V8 engine and Chromium as its renderer, Tauri uses Rust at its core and introduces TAO and WRY as tools for communication. So, compared to JavaScript, Rust is much closer to the machine, right? According to several sources, Tauri excels in memory management and bundle size compared to Electron. For example, see this source: ",[75,429,430],{"href":430,"rel":431},"https:\u002F\u002Fwww.levminer.com\u002Fblog\u002Ftauri-vs-electron",[79],". Of course, Tauri also has a faster startup time than Electron. Okay, that's enough intermezzo—let's move on to installation.",[20,434,436],{"id":435},"development-experience","Development Experience",[25,438,439,440,444],{},"For a more complete installation guide, visit ",[75,441,442],{"href":442,"rel":443},"https:\u002F\u002Ftauri.app",[79],". But for starters, they already support popular frameworks like:",[346,446,447,454,461,468],{},[349,448,449],{},[75,450,453],{"href":451,"rel":452},"https:\u002F\u002Fnextjs.org\u002F",[79],"NextJS",[349,455,456],{},[75,457,460],{"href":458,"rel":459},"https:\u002F\u002Fkit.svelte.dev\u002F",[79],"SvelteKit",[349,462,463],{},[75,464,467],{"href":465,"rel":466},"https:\u002F\u002Fvitejs.dev\u002F",[79],"Vite",[349,469,470],{},[29,471,472],{},"other frameworks",[20,474,476],{"id":475},"should-you-migrate","Should You Migrate?",[25,478,479],{},"For those who have tried or produced products using electron.js, should you migrate to Tauri? My answer is yes, but with some notes:",[346,481,482,485,488],{},[349,483,484],{},"Tauri uses Rust in some cases. It's basic, but Rust is a high-level language that not everyone is familiar with.",[349,486,487],{},"Tauri's sponsorship is still limited compared to Electron, which has been around longer, so it will take time to develop features that match Electron.",[349,489,490],{},"There are not yet any showcase companies using Tauri as one of their technologies.",[20,492,494],{"id":493},"references","References",[346,496,497,504,511,518,525,532,537,542,547],{},[349,498,499],{},[75,500,503],{"href":501,"rel":502},"https:\u002F\u002Ftauri.app\u002F",[79],"Tauri",[349,505,506],{},[75,507,510],{"href":508,"rel":509},"https:\u002F\u002Fwww.electronjs.org\u002F",[79],"Electron.js",[349,512,513],{},[75,514,517],{"href":515,"rel":516},"https:\u002F\u002Fwww.rust-lang.org\u002F",[79],"Rust",[349,519,520],{},[75,521,524],{"href":522,"rel":523},"https:\u002F\u002Fgithub.com\u002Ftauri-apps\u002Ftao",[79],"TAO",[349,526,527],{},[75,528,531],{"href":529,"rel":530},"https:\u002F\u002Fgithub.com\u002Ftauri-apps\u002Fwry",[79],"WRY",[349,533,534],{},[75,535,453],{"href":451,"rel":536},[79],[349,538,539],{},[75,540,460],{"href":458,"rel":541},[79],[349,543,544],{},[75,545,467],{"href":465,"rel":546},[79],[349,548,549],{},[75,550,552],{"href":430,"rel":551},[79],"Tauri vs Electron Comparison",{"title":242,"searchDepth":243,"depth":243,"links":554},[555,556,557],{"id":435,"depth":243,"text":436},{"id":475,"depth":243,"text":476},{"id":493,"depth":243,"text":494},"2022-12-06","Who hasn't heard of electron.js? The go-to multi-platform desktop development framework for Linux, Mac, and Windows. Now, there's a new competitor: Tauri JS.","\u002Fimages\u002Fblog\u002Ftauri.png",{},"\u002Fblog\u002Ftauri-app-si-calon-pesaing-electron-js-yang-ditulis-menggunakan-rust",{"title":419,"description":559},{"loc":562},"blog\u002Ftauri-app-si-calon-pesaing-electron-js-yang-ditulis-menggunakan-rust","6hScf7RNBobCmptTM3Ez1mB6cTJ205J08I_L_xvZ_B0",{"id":568,"title":569,"body":570,"date":676,"description":677,"extension":274,"image":678,"meta":679,"navigation":277,"path":680,"seo":681,"sitemap":682,"stem":683,"__hash__":684},"blog\u002Fblog\u002Ffleet-dianggap-pesaing-baru-visual-studio-code-ngga-overclaim.md","Is Fleet the New Competitor to Visual Studio Code? Not Overclaiming?",{"type":17,"value":571,"toc":671},[572,575,578,581,589,592,596,613,617,620,627,630,636,639,643,654,657,668],[25,573,574],{},"Who doesn't know JetBrains? This software company has been around the world of IDEs for a long time. They've made many, such as PHPStorm, IntelliJ, WebStorm, RubyMine, GoLand, and even Android Studio. Yes, you heard that right—even though Google owns Android, when it comes to IDEs, they trust JetBrains' technology, and until now, there hasn't been an official Android IDE fully made by Google itself.",[25,576,577],{},"In fact, guys, the Kotlin language was also designed and developed by them, so indirectly, they're a big tech company, right? Okay, let's not get too sidetracked talking about JetBrains. What about Fleet? Well, VSCode's dominance as the free code editor for the masses might take time to be challenged, especially since GitHub was acquired by Microsoft, which led to one of their competitors, Atom, being discontinued.",[25,579,580],{},"So what's left? Sublime? NPP? VIM? OMG, too few plugins. Sure, they're simple, but not as powerful as VSCode. So what is Fleet? Like most big companies, JetBrains as the parent wants to cover all IDE business lines, one of which is the Polyglot side. What is polyglot? Simply put, it's an IDE that lets you modify and run coding tools in the same application, unlike previous JetBrains IDEs that focused on a single programming language—polyglot covers them all.",[25,582,583,584,588],{},"Fleet's debut started on November 29, 2021, from ",[75,585,586],{"href":586,"rel":587},"https:\u002F\u002Fblog.jetbrains.com\u002Fblog\u002F2021\u002F11\u002F29\u002Fwelcome-to-fleet\u002F",[79],", which explained they would release an IDE capable of integrating with all JetBrains services. The good news is, this IDE is said to be free as of this article's writing, so naturally, many are curious about it, especially since JetBrains services are known to be expensive—even costing millions of rupiah for just one IDE.",[25,590,591],{},"This brings fresh air for those looking for a VSCode alternative, especially since Fleet has a Smart Mode feature that enables indexing like other JetBrains IDEs out of the box, without needing to install any extensions. So that's a brief overview of JetBrains. Now, is the IDE as good as they say? Hopefully yes, but wait...",[20,593,595],{"id":594},"how-to-install","How to Install",[597,598,599,607,610],"ol",{},[349,600,601,602,606],{},"Go to the Fleet page at ",[75,603,604],{"href":604,"rel":605},"https:\u002F\u002Fwww.jetbrains.com\u002Ffleet\u002F",[79]," and click download",[349,608,609],{},"You will be redirected to the JetBrains Toolbox download page",[349,611,612],{},"Download the application and install",[20,614,616],{"id":615},"first-impression","First Impression",[25,618,619],{},"By default, Fleet just looks like an ordinary code editor, even more like Sublime Text—there's nothing special like in VSCode. Take a look below:",[25,621,622],{},[623,624],"img",{"alt":625,"src":626},"fleet","\u002Fimages\u002Fblog\u002Ffleet-preview.png",[25,628,629],{},"Looks plain, right? But wait, pay attention to the top right toolbar—there's a flash icon like lightning?",[25,631,632],{},[623,633],{"alt":634,"src":635},"smart mode","\u002Fimages\u002Fblog\u002Ffleet-smart-mode.png",[25,637,638],{},"They will sync and index all lines of code, including node modules, to provide suggestions and mapping when developing a project. For now, only a few programming languages are supported by Fleet, but more will be supported in the future. Interested? Read my overall review first.",[20,640,642],{"id":641},"overall-review","Overall Review",[346,644,645,648,651],{},[349,646,647],{},"The tools and UI are not as familiar as typical JetBrains IDEs",[349,649,650],{},"It takes a bit of time to adjust from VSCode",[349,652,653],{},"The installation process is complicated; you can't go directly to the app. You have to use the toolbox",[25,655,656],{},"That's all for my initial experience using Fleet as a JetBrains and VSCode user. In my opinion, there's still a lot to improve, and for now, I can't recommend switching yet. Oh, by the way, Fleet is available for all OS:",[346,658,659,662,665],{},[349,660,661],{},"Linux",[349,663,664],{},"Windows",[349,666,667],{},"MacOS",[25,669,670],{},"Happy code night ☕️",{"title":242,"searchDepth":243,"depth":243,"links":672},[673,674,675],{"id":594,"depth":243,"text":595},{"id":615,"depth":243,"text":616},{"id":641,"depth":243,"text":642},"2022-11-29","After moving from closed preview to public preview, how good is Fleet IDE, which is said to be a competitor to Visual Studio Code? Can it really compete?","\u002Fimages\u002Fblog\u002Ffleet.png",{},"\u002Fblog\u002Ffleet-dianggap-pesaing-baru-visual-studio-code-ngga-overclaim",{"title":569,"description":677},{"loc":680},"blog\u002Ffleet-dianggap-pesaing-baru-visual-studio-code-ngga-overclaim","Zv7Bh9Rm8EErWaN6Akuw_9N1O18jQqAUMGdMjPhPayk",{"id":686,"title":687,"body":688,"date":1101,"description":1102,"extension":274,"image":1103,"meta":1104,"navigation":277,"path":1105,"seo":1106,"sitemap":1107,"stem":1108,"__hash__":1109},"blog\u002Fblog\u002Fdynamic-properties-deprecated-di-php-8-2-mimpi-buruk.md","Dynamic Properties deprecated di PHP 8.2? Mimpi buruk?",{"type":17,"value":689,"toc":1096},[690,694,697,774,778,789,840,843,895,898,970,1004,1008,1015,1079,1092],[20,691,693],{"id":692},"update","Update",[25,695,696],{},"Seperti biasa setelah melakukan upgrade minor dari php 8.0 ke 8.1, php group kembali memberikan rilis informasi bahwa mereka sedang mengerjakan update php 8.2 yang nantinya akan memberikan update antara lain sebagai berikut (yang aku notice terbesar ya)",[346,698,699,706,716,719,726,736,743,749,754,761,764],{},[349,700,701,702],{},"Class ",[703,704,705],"code",{},"readonly",[349,707,708,709,712,713],{},"Union type baru ",[703,710,711],{},"true"," dan ",[703,714,715],{},"false",[349,717,718],{},"Dukungan redaksi nilai Parameter Sensitif",[349,720,721,722,725],{},"Extensi ",[703,723,724],{},"Random"," baru",[349,727,728,729,732,733],{},"MySQLi: New ",[703,730,731],{},"mysqli_execute_query"," function and ",[703,734,735],{},"mysqli::execute_query method",[349,737,738,739,742],{},"Fungsi ",[703,740,741],{},"openssl_cipher_key_length"," yang diperbarui",[349,744,745,746],{},"Pengaturan permission untuk ",[703,747,748],{},"error_log_mode",[349,750,751,752],{},"OpenSSL: Fungsi baru ",[703,753,741],{},[349,755,756,757,760],{},"Dukungan ",[703,758,759],{},"const"," untuk trait",[349,762,763],{},"Dynamic Property Deprecations",[349,765,766],{},[29,767,768,769],{},"etc. Selengkapnya bisa dibaca ",[75,770,773],{"href":771,"rel":772},"https:\u002F\u002Fphp.watch\u002Fversions\u002F8.2",[79],"di sini",[20,775,777],{"id":776},"big-notes","Big Notes",[25,779,780,781,784,785,788],{},"Namun dari perubahan diatas, ada perubahan yang paling menonjol menurut gw berdasarkan pengalaman gw dalam develop sebuah software (backend) menggunakan php, yaitu ",[94,782,783],{},"Dynamic Property"," yang menjadi deprecated di versi baru ini, asumsinya kita tidak bisa lagi declare sebuah variabel yang berisi ",[703,786,787],{},"class"," lalu write property langsung, kaya dibawah ini deh",[790,791,795],"pre",{"className":792,"code":793,"language":794,"meta":242,"style":242},"language-php shiki shiki-themes github-light github-dark","$var = new Member();\n$var->name = \"Yanuar\";\n","php",[703,796,797,820],{"__ignoreMap":242},[798,799,802,806,810,813,817],"span",{"class":800,"line":801},"line",1,[798,803,805],{"class":804},"sVt8B","$var ",[798,807,809],{"class":808},"szBVR","=",[798,811,812],{"class":808}," new",[798,814,816],{"class":815},"sj4cs"," Member",[798,818,819],{"class":804},"();\n",[798,821,822,825,828,831,833,837],{"class":800,"line":243},[798,823,824],{"class":804},"$var",[798,826,827],{"class":808},"->",[798,829,830],{"class":804},"name ",[798,832,809],{"class":808},[798,834,836],{"class":835},"sZZnC"," \"Yanuar\"",[798,838,839],{"class":804},";\n",[25,841,842],{},"Kalau masih maksa buat pake dynamic prop di php 8.2 bakal munculin output kaya dibawah ini, by default loh ya!",[790,844,848],{"className":845,"code":846,"language":847,"meta":242,"style":242},"language-shell shiki shiki-themes github-light github-dark","Deprecated: Creation of dynamic property Member::$name is deprecated in ... on line ...\n","shell",[703,849,850],{"__ignoreMap":242},[798,851,852,856,859,862,865,868,871,874,877,880,883,886,889,892],{"class":800,"line":801},[798,853,855],{"class":854},"sScJk","Deprecated:",[798,857,858],{"class":835}," Creation",[798,860,861],{"class":835}," of",[798,863,864],{"class":835}," dynamic",[798,866,867],{"class":835}," property",[798,869,870],{"class":835}," Member::",[798,872,873],{"class":804},"$name ",[798,875,876],{"class":835},"is",[798,878,879],{"class":835}," deprecated",[798,881,882],{"class":835}," in",[798,884,885],{"class":835}," ...",[798,887,888],{"class":835}," on",[798,890,891],{"class":835}," line",[798,893,894],{"class":835}," ...\n",[25,896,897],{},"Hal di atas berlaku juga untuk constructor milik class itu sendiri loh ya, kaya gini",[790,899,901],{"className":792,"code":900,"language":794,"meta":242,"style":242},"class Member {\n    public function __construct() {\n        $this->name = 'test';\n    }\n}\n\nnew Member();\n",[703,902,903,912,926,942,948,954,960],{"__ignoreMap":242},[798,904,905,907,909],{"class":800,"line":801},[798,906,787],{"class":808},[798,908,816],{"class":854},[798,910,911],{"class":804}," {\n",[798,913,914,917,920,923],{"class":800,"line":243},[798,915,916],{"class":808},"    public",[798,918,919],{"class":808}," function",[798,921,922],{"class":815}," __construct",[798,924,925],{"class":804},"() {\n",[798,927,928,931,933,935,937,940],{"class":800,"line":251},[798,929,930],{"class":815},"        $this",[798,932,827],{"class":808},[798,934,830],{"class":804},[798,936,809],{"class":808},[798,938,939],{"class":835}," 'test'",[798,941,839],{"class":804},[798,943,945],{"class":800,"line":944},4,[798,946,947],{"class":804},"    }\n",[798,949,951],{"class":800,"line":950},5,[798,952,953],{"class":804},"}\n",[798,955,957],{"class":800,"line":956},6,[798,958,959],{"emptyLinePlaceholder":277},"\n",[798,961,963,966,968],{"class":800,"line":962},7,[798,964,965],{"class":808},"new",[798,967,816],{"class":815},[798,969,819],{"class":804},[790,971,972],{"className":845,"code":846,"language":847,"meta":242,"style":242},[703,973,974],{"__ignoreMap":242},[798,975,976,978,980,982,984,986,988,990,992,994,996,998,1000,1002],{"class":800,"line":801},[798,977,855],{"class":854},[798,979,858],{"class":835},[798,981,861],{"class":835},[798,983,864],{"class":835},[798,985,867],{"class":835},[798,987,870],{"class":835},[798,989,873],{"class":804},[798,991,876],{"class":835},[798,993,879],{"class":835},[798,995,882],{"class":835},[798,997,885],{"class":835},[798,999,888],{"class":835},[798,1001,891],{"class":835},[798,1003,894],{"class":835},[20,1005,1007],{"id":1006},"solutions","Solutions",[25,1009,1010,1011,1014],{},"Ngeri kan? Bayangin seorang devOps atau kamu ngga sengaja upgrade pake package manager dari php 8.1 ke 8.2, apa ngga ambruk struktur kodinganmu tuh hahaha. Tapi tunggu sebentar, ada sesuatu yang mungkin bisa buat kamu agak bernafas lebih panjang, yaitu ",[703,1012,1013],{},"#[AllowDynamicProperties]"," yap allow dynamic properties, mungkin php core engineer ngga bakal semudah itu buat hilangin dynamic property dari semua sisi karena yaa udah mendarah daging ke developer PHP di dunia? mungkin? Cara aplikasinya simpel kok, tinggal declare \u002F write line tersebut diatas pembuatan class kaya dibawah deh",[790,1016,1018],{"className":792,"code":1017,"language":794,"meta":242,"style":242}," #[AllowDynamicProperties]\nclass Member {\n    public function __construct() {\n        $this->name = 'test';\n    }\n}\nnew Member();\n",[703,1019,1020,1031,1039,1049,1063,1067,1071],{"__ignoreMap":242},[798,1021,1022,1025,1028],{"class":800,"line":801},[798,1023,1024],{"class":804}," #[",[798,1026,1027],{"class":815},"AllowDynamicProperties",[798,1029,1030],{"class":804},"]\n",[798,1032,1033,1035,1037],{"class":800,"line":243},[798,1034,787],{"class":808},[798,1036,816],{"class":854},[798,1038,911],{"class":804},[798,1040,1041,1043,1045,1047],{"class":800,"line":251},[798,1042,916],{"class":808},[798,1044,919],{"class":808},[798,1046,922],{"class":815},[798,1048,925],{"class":804},[798,1050,1051,1053,1055,1057,1059,1061],{"class":800,"line":944},[798,1052,930],{"class":815},[798,1054,827],{"class":808},[798,1056,830],{"class":804},[798,1058,809],{"class":808},[798,1060,939],{"class":835},[798,1062,839],{"class":804},[798,1064,1065],{"class":800,"line":950},[798,1066,947],{"class":804},[798,1068,1069],{"class":800,"line":956},[798,1070,953],{"class":804},[798,1072,1073,1075,1077],{"class":800,"line":962},[798,1074,965],{"class":808},[798,1076,816],{"class":815},[798,1078,819],{"class":804},[25,1080,1081,1082,1085,1086,1091],{},"Voila, bisa kaan? Ada cara lain sebetulnya yaitu menggunakan sesuatu yang belum mungkin deprecated yaitu ",[703,1083,1084],{},"stdClass",", gimana caranya? Extend aja classnya pake stdClass, that's it. Buat artikel lebih lengkap bisa cek ",[75,1087,1090],{"href":1088,"rel":1089},"https:\u002F\u002Fphp.watch\u002Fversions\u002F8.2\u002Fdynamic-properties-deprecated",[79],"disini nih",". Soo ya, makin kesini php makin banyak perubahan, hopefully bakal bersaing bahasa program lain yang lebih muda dan baru. Sekian dulu post gue kali ini, thanks ☕️",[1093,1094,1095],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":242,"searchDepth":243,"depth":243,"links":1097},[1098,1099,1100],{"id":692,"depth":243,"text":693},{"id":776,"depth":243,"text":777},{"id":1006,"depth":243,"text":1007},"2022-11-28","Di PHP versi 8.2 terdapat update yang dianggap para developer php seperti gw kaget, yap dynamic property menjadi deprecated by default, Lho kok bisa?","\u002Fimages\u002Fblog\u002Fdynamic-prop.png",{},"\u002Fblog\u002Fdynamic-properties-deprecated-di-php-8-2-mimpi-buruk",{"title":687,"description":1102},{"loc":1105},"blog\u002Fdynamic-properties-deprecated-di-php-8-2-mimpi-buruk","ksm40ETFIKcYsqwVGGpP-oWS3uXw38PZvKxhRet-TaU",{"id":1111,"title":1112,"body":1113,"date":2217,"description":2218,"extension":274,"image":2219,"meta":2220,"navigation":277,"path":2221,"seo":2222,"sitemap":2223,"stem":2224,"__hash__":2225},"blog\u002Fblog\u002Fphp-8.md","Sudah sejauh mana belajar PHP? Udah tau versi 8???",{"type":17,"value":1114,"toc":2205},[1115,1118,1122,1125,1160,1163,1184,1187,1191,1194,1262,1266,1273,1434,1508,1512,1538,1607,1611,1621,1677,1681,1684,1816,1819,1849,1853,1856,1941,2006,2010,2084,2087,2091,2108,2173,2177,2193,2199,2202],[25,1116,1117],{},"25 November 2021, yap beberapa hari sebelum artikel ini dibuat versi baru dari PHP (Hypertext Preprocessor) baru saja dirilis yaitu ke 8.1.0, duh padahal existing project masih pake 7.3, 7.4 😒. Yaaa begitulah teknologi, kalo ngga susah payah buat update ya bakal ketinggalan, but eits ngga ada kata terlambat guys, masih ada waktu buaat belajar. Buat yang masih pake php 7.x atau dibawahnya apa aja sih yang baru di versi 8 dan 8.1?? Berikut aku jelasin sedikit dari sudut pandang seorang developer PHP 😂",[20,1119,1121],{"id":1120},"named-arguments","Named Arguments",[25,1123,1124],{},"Pemain lama php pasti sering dong ngalamin ketika ingin mengisi dua argument dalam function yang ngga berurutan, misal mau isi argumen #1 dan #3 tapi harus mengisi #2 padahal udah ada tuh default value nya. Nah di versi php 8 keatas, hal itu udah diatasi dengan cara tinggal panggil aja named variable yang perlu di isi buat gambaran aku kasih deh sample php 7 nih dibawah",[790,1126,1128],{"className":792,"code":1127,"language":794,"meta":242,"style":242},"htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);\n",[703,1129,1130],{"__ignoreMap":242},[798,1131,1132,1135,1138,1141,1144,1147,1150,1153,1155,1157],{"class":800,"line":801},[798,1133,1134],{"class":815},"htmlspecialchars",[798,1136,1137],{"class":804},"($string, ",[798,1139,1140],{"class":815},"ENT_COMPAT",[798,1142,1143],{"class":808}," |",[798,1145,1146],{"class":815}," ENT_HTML401",[798,1148,1149],{"class":804},", ",[798,1151,1152],{"class":835},"'UTF-8'",[798,1154,1149],{"class":804},[798,1156,715],{"class":815},[798,1158,1159],{"class":804},");\n",[25,1161,1162],{},"Penasaran di php8? Nih",[790,1164,1166],{"className":792,"code":1165,"language":794,"meta":242,"style":242},"htmlspecialchars($string, double_encode: false);\n",[703,1167,1168],{"__ignoreMap":242},[798,1169,1170,1172,1174,1177,1180,1182],{"class":800,"line":801},[798,1171,1134],{"class":815},[798,1173,1137],{"class":804},[798,1175,1176],{"class":854},"double_encode",[798,1178,1179],{"class":804},": ",[798,1181,715],{"class":815},[798,1183,1159],{"class":804},[25,1185,1186],{},"Udah kebaca?, di sample diatas kita cuma pengin ngisi argument pertama karena wajib tuh ngga dan ngga ada default value, terus argumen #2 dan #3 mau kita biarin dia pake argumen asli, nah daripada mengisi ulang data default ke argumen yang sama, di php 8 bisa dilompati dengan cara memanggil nama variabel diikuti titik dua lalu value, mudah kan hehe.",[20,1188,1190],{"id":1189},"phpdoc-attributes","PHPDoc Attributes",[25,1192,1193],{},"Yang bekerja dengan tim pasti perlu dan sering deh buat menulis dokumentasi method atau function dengan php, tapi pernah ngga sih bosen dan ribet banget kalo pake html tag dan simbol bintang (*) setiap kali mau buat dokumentasi, di versi baru bisa pake metadata yang lebih terstruktur, tapi seperti biasa metode lama tetep bisa kamu pake kok",[790,1195,1197],{"className":792,"code":1196,"language":794,"meta":242,"style":242},"class PostsController\n{\n    #[Route(\"\u002Fapi\u002Fposts\u002F{id}\", methods: [\"GET\"])]\n    public function get($id) { \u002F* ... *\u002F }\n}\n",[703,1198,1199,1206,1211,1239,1258],{"__ignoreMap":242},[798,1200,1201,1203],{"class":800,"line":801},[798,1202,787],{"class":808},[798,1204,1205],{"class":854}," PostsController\n",[798,1207,1208],{"class":800,"line":243},[798,1209,1210],{"class":804},"{\n",[798,1212,1213,1216,1219,1222,1225,1227,1230,1233,1236],{"class":800,"line":251},[798,1214,1215],{"class":804},"    #[",[798,1217,1218],{"class":815},"Route",[798,1220,1221],{"class":804},"(",[798,1223,1224],{"class":835},"\"\u002Fapi\u002Fposts\u002F{id}\"",[798,1226,1149],{"class":804},[798,1228,1229],{"class":854},"methods",[798,1231,1232],{"class":804},": [",[798,1234,1235],{"class":835},"\"GET\"",[798,1237,1238],{"class":804},"])]\n",[798,1240,1241,1243,1245,1248,1251,1255],{"class":800,"line":944},[798,1242,916],{"class":808},[798,1244,919],{"class":808},[798,1246,1247],{"class":854}," get",[798,1249,1250],{"class":804},"($id) { ",[798,1252,1254],{"class":1253},"sJ8bj","\u002F* ... *\u002F",[798,1256,1257],{"class":804}," }\n",[798,1259,1260],{"class":800,"line":950},[798,1261,953],{"class":804},[20,1263,1265],{"id":1264},"constructor-property-promotion","Constructor property promotion",[25,1267,1268,1269,1272],{},"Nah ini yang menurutku revolusioner buat developer php veteran, ketika develop sebuah class atau service pasti sering tuh buat property terus buat mengisikan value kita harus nambah action di bagian ",[703,1270,1271],{},"_construct"," agak belibet kan? Harus deklarasi parameter, set argument construct, terus nambah action.... Nah gimana kalo cuma set argument aja udah cukup? Yap di versi 8 ada fitur namanya constructor property promotion, jadiii semua argument yang dibentuk menyerupai property didalam argument construct akan dinaikkan posisinya menjadi property, atau dalam kata lain argument itu bisa diakses sebagai property, buat gambaran bisa lihat deh, yang dibawah ini versi lama dan bawahnya lagi versi baru",[790,1274,1276],{"className":792,"code":1275,"language":794,"meta":242,"style":242},"class Point {\n  public float $x;\n  public float $y;\n  public float $z;\n\n  public function __construct(\n    float $x = 0.0,\n    float $y = 0.0,\n    float $z = 0.0\n  ) {\n    $this->x = $x;\n    $this->y = $y;\n    $this->z = $z;\n  }\n}\n",[703,1277,1278,1287,1298,1307,1316,1320,1331,1347,1361,1374,1380,1395,1409,1423,1429],{"__ignoreMap":242},[798,1279,1280,1282,1285],{"class":800,"line":801},[798,1281,787],{"class":808},[798,1283,1284],{"class":854}," Point",[798,1286,911],{"class":804},[798,1288,1289,1292,1295],{"class":800,"line":243},[798,1290,1291],{"class":808},"  public",[798,1293,1294],{"class":808}," float",[798,1296,1297],{"class":804}," $x;\n",[798,1299,1300,1302,1304],{"class":800,"line":251},[798,1301,1291],{"class":808},[798,1303,1294],{"class":808},[798,1305,1306],{"class":804}," $y;\n",[798,1308,1309,1311,1313],{"class":800,"line":944},[798,1310,1291],{"class":808},[798,1312,1294],{"class":808},[798,1314,1315],{"class":804}," $z;\n",[798,1317,1318],{"class":800,"line":950},[798,1319,959],{"emptyLinePlaceholder":277},[798,1321,1322,1324,1326,1328],{"class":800,"line":956},[798,1323,1291],{"class":808},[798,1325,919],{"class":808},[798,1327,922],{"class":815},[798,1329,1330],{"class":804},"(\n",[798,1332,1333,1336,1339,1341,1344],{"class":800,"line":962},[798,1334,1335],{"class":808},"    float",[798,1337,1338],{"class":804}," $x ",[798,1340,809],{"class":808},[798,1342,1343],{"class":815}," 0.0",[798,1345,1346],{"class":804},",\n",[798,1348,1350,1352,1355,1357,1359],{"class":800,"line":1349},8,[798,1351,1335],{"class":808},[798,1353,1354],{"class":804}," $y ",[798,1356,809],{"class":808},[798,1358,1343],{"class":815},[798,1360,1346],{"class":804},[798,1362,1364,1366,1369,1371],{"class":800,"line":1363},9,[798,1365,1335],{"class":808},[798,1367,1368],{"class":804}," $z ",[798,1370,809],{"class":808},[798,1372,1373],{"class":815}," 0.0\n",[798,1375,1377],{"class":800,"line":1376},10,[798,1378,1379],{"class":804},"  ) {\n",[798,1381,1383,1386,1388,1391,1393],{"class":800,"line":1382},11,[798,1384,1385],{"class":815},"    $this",[798,1387,827],{"class":808},[798,1389,1390],{"class":804},"x ",[798,1392,809],{"class":808},[798,1394,1297],{"class":804},[798,1396,1398,1400,1402,1405,1407],{"class":800,"line":1397},12,[798,1399,1385],{"class":815},[798,1401,827],{"class":808},[798,1403,1404],{"class":804},"y ",[798,1406,809],{"class":808},[798,1408,1306],{"class":804},[798,1410,1412,1414,1416,1419,1421],{"class":800,"line":1411},13,[798,1413,1385],{"class":815},[798,1415,827],{"class":808},[798,1417,1418],{"class":804},"z ",[798,1420,809],{"class":808},[798,1422,1315],{"class":804},[798,1424,1426],{"class":800,"line":1425},14,[798,1427,1428],{"class":804},"  }\n",[798,1430,1432],{"class":800,"line":1431},15,[798,1433,953],{"class":804},[790,1435,1437],{"className":792,"code":1436,"language":794,"meta":242,"style":242},"class Point {\n  public function __construct(\n    public float $x = 0.0,\n    public float $y = 0.0,\n    public float $z = 0.0,\n  ) {}\n}\n",[703,1438,1439,1447,1457,1471,1485,1499,1504],{"__ignoreMap":242},[798,1440,1441,1443,1445],{"class":800,"line":801},[798,1442,787],{"class":808},[798,1444,1284],{"class":854},[798,1446,911],{"class":804},[798,1448,1449,1451,1453,1455],{"class":800,"line":243},[798,1450,1291],{"class":808},[798,1452,919],{"class":808},[798,1454,922],{"class":815},[798,1456,1330],{"class":804},[798,1458,1459,1461,1463,1465,1467,1469],{"class":800,"line":251},[798,1460,916],{"class":808},[798,1462,1294],{"class":808},[798,1464,1338],{"class":804},[798,1466,809],{"class":808},[798,1468,1343],{"class":815},[798,1470,1346],{"class":804},[798,1472,1473,1475,1477,1479,1481,1483],{"class":800,"line":944},[798,1474,916],{"class":808},[798,1476,1294],{"class":808},[798,1478,1354],{"class":804},[798,1480,809],{"class":808},[798,1482,1343],{"class":815},[798,1484,1346],{"class":804},[798,1486,1487,1489,1491,1493,1495,1497],{"class":800,"line":950},[798,1488,916],{"class":808},[798,1490,1294],{"class":808},[798,1492,1368],{"class":804},[798,1494,809],{"class":808},[798,1496,1343],{"class":815},[798,1498,1346],{"class":804},[798,1500,1501],{"class":800,"line":956},[798,1502,1503],{"class":804},"  ) {}\n",[798,1505,1506],{"class":800,"line":962},[798,1507,953],{"class":804},[20,1509,1511],{"id":1510},"union-types","Union types",[25,1513,1514,1515,1518,1519,1522,1523,1526,1527,1530,1531,1522,1534,1537],{},"Tipe bawang, aneh ya wkwkw tapi pasti developer bahasa seperti javascript udah sering tau jenis tipe data ini, singkatnya sebuah variabel kita bisa berikan akses tipe data bermacam-macam dan akan throw ketika tipe data diluar yang di set di inputkan. Contoh kasusnya adalah gini, kita mau set property private ",[703,1516,1517],{},"$number"," hanya bisa ",[29,1520,1521],{},"float"," atau ",[29,1524,1525],{},"int",", nah di php 7.4 kita tinggal buat aja ",[703,1528,1529],{},"private float $number"," terus ketika number itu kita set maka diberi validasi ",[703,1532,1533],{},"is_float",[703,1535,1536],{},"is_int"," bukan?? Atau malah di versi dibawah 7.4 kita perlu effort lebih dengan melakukan pengecekan dua kali, di versi ini ngga perlu lagi begindang, cukup waktu deklarasi property tanpa banyak cingcong 🤣",[790,1539,1541],{"className":792,"code":1540,"language":794,"meta":242,"style":242},"class Number {\n  public function __construct(\n    private int|float $number\n  ) {}\n}\n\nnew Number('NaN'); \u002F\u002F Akan error ketika diisi string, karena $number cuma menerima int dan float\n",[703,1542,1543,1552,1562,1578,1582,1586,1590],{"__ignoreMap":242},[798,1544,1545,1547,1550],{"class":800,"line":801},[798,1546,787],{"class":808},[798,1548,1549],{"class":854}," Number",[798,1551,911],{"class":804},[798,1553,1554,1556,1558,1560],{"class":800,"line":243},[798,1555,1291],{"class":808},[798,1557,919],{"class":808},[798,1559,922],{"class":815},[798,1561,1330],{"class":804},[798,1563,1564,1567,1570,1573,1575],{"class":800,"line":251},[798,1565,1566],{"class":808},"    private",[798,1568,1569],{"class":808}," int",[798,1571,1572],{"class":804},"|",[798,1574,1521],{"class":808},[798,1576,1577],{"class":804}," $number\n",[798,1579,1580],{"class":800,"line":944},[798,1581,1503],{"class":804},[798,1583,1584],{"class":800,"line":950},[798,1585,953],{"class":804},[798,1587,1588],{"class":800,"line":956},[798,1589,959],{"emptyLinePlaceholder":277},[798,1591,1592,1594,1596,1598,1601,1604],{"class":800,"line":962},[798,1593,965],{"class":808},[798,1595,1549],{"class":815},[798,1597,1221],{"class":804},[798,1599,1600],{"class":835},"'NaN'",[798,1602,1603],{"class":804},"); ",[798,1605,1606],{"class":1253},"\u002F\u002F Akan error ketika diisi string, karena $number cuma menerima int dan float\n",[20,1608,1610],{"id":1609},"match-expression","Match expression",[25,1612,1613,1614,712,1617,1620],{},"Pengguna switch expression pasti sering mengalami deh kalau value string dan value numeric karena bentuknya aja yang mirip cuma beda di pembungkus lolos case condition? Misal ",[703,1615,1616],{},"1",[703,1618,1619],{},"'1'"," akan dianggap sama oleh case ya karena memang kelemahan switch itu 😢. Di match expression hal ini berhasil diatasi, jadi hanya value yang memiliki tipe data dan kondisi yang sama persis yang akan lolos case condition",[790,1622,1624],{"className":792,"code":1623,"language":794,"meta":242,"style":242},"echo match (1) {\n  '1' => \"Oh no!\",\n  1 => \"This is what I expected\",\n};\n\u002F\u002F> Jadi bisa aja kita buat ekspresi yang berbeda untuk beneran integer sama beneran string yang menyamar\n",[703,1625,1626,1642,1655,1667,1672],{"__ignoreMap":242},[798,1627,1628,1631,1634,1637,1639],{"class":800,"line":801},[798,1629,1630],{"class":815},"echo",[798,1632,1633],{"class":808}," match",[798,1635,1636],{"class":804}," (",[798,1638,1616],{"class":815},[798,1640,1641],{"class":804},") {\n",[798,1643,1644,1647,1650,1653],{"class":800,"line":243},[798,1645,1646],{"class":835},"  '1'",[798,1648,1649],{"class":808}," =>",[798,1651,1652],{"class":835}," \"Oh no!\"",[798,1654,1346],{"class":804},[798,1656,1657,1660,1662,1665],{"class":800,"line":251},[798,1658,1659],{"class":815},"  1",[798,1661,1649],{"class":808},[798,1663,1664],{"class":835}," \"This is what I expected\"",[798,1666,1346],{"class":804},[798,1668,1669],{"class":800,"line":944},[798,1670,1671],{"class":804},"};\n",[798,1673,1674],{"class":800,"line":950},[798,1675,1676],{"class":1253},"\u002F\u002F> Jadi bisa aja kita buat ekspresi yang berbeda untuk beneran integer sama beneran string yang menyamar\n",[20,1678,1680],{"id":1679},"nullsafe-operator","Nullsafe operator",[25,1682,1683],{},"Ngga mau kalah sama flutter dong 😂, yaa bener di php 8 daripada harus mengecek satu per satu, nglakuin perulangan buat ngecek setiap element kaya dibawah ini",[790,1685,1687],{"className":792,"code":1686,"language":794,"meta":242,"style":242},"$country =  null;\n\nif ($session !== null) {\n  $user = $session->user;\n\n  if ($user !== null) {\n    $address = $user->getAddress();\n\n    if ($address !== null) {\n      $country = $address->country;\n    }\n  }\n}\n",[703,1688,1689,1701,1705,1721,1736,1740,1754,1771,1775,1789,1804,1808,1812],{"__ignoreMap":242},[798,1690,1691,1694,1696,1699],{"class":800,"line":801},[798,1692,1693],{"class":804},"$country ",[798,1695,809],{"class":808},[798,1697,1698],{"class":815},"  null",[798,1700,839],{"class":804},[798,1702,1703],{"class":800,"line":243},[798,1704,959],{"emptyLinePlaceholder":277},[798,1706,1707,1710,1713,1716,1719],{"class":800,"line":251},[798,1708,1709],{"class":808},"if",[798,1711,1712],{"class":804}," ($session ",[798,1714,1715],{"class":808},"!==",[798,1717,1718],{"class":815}," null",[798,1720,1641],{"class":804},[798,1722,1723,1726,1728,1731,1733],{"class":800,"line":944},[798,1724,1725],{"class":804},"  $user ",[798,1727,809],{"class":808},[798,1729,1730],{"class":804}," $session",[798,1732,827],{"class":808},[798,1734,1735],{"class":804},"user;\n",[798,1737,1738],{"class":800,"line":950},[798,1739,959],{"emptyLinePlaceholder":277},[798,1741,1742,1745,1748,1750,1752],{"class":800,"line":956},[798,1743,1744],{"class":808},"  if",[798,1746,1747],{"class":804}," ($user ",[798,1749,1715],{"class":808},[798,1751,1718],{"class":815},[798,1753,1641],{"class":804},[798,1755,1756,1759,1761,1764,1766,1769],{"class":800,"line":962},[798,1757,1758],{"class":804},"    $address ",[798,1760,809],{"class":808},[798,1762,1763],{"class":804}," $user",[798,1765,827],{"class":808},[798,1767,1768],{"class":854},"getAddress",[798,1770,819],{"class":804},[798,1772,1773],{"class":800,"line":1349},[798,1774,959],{"emptyLinePlaceholder":277},[798,1776,1777,1780,1783,1785,1787],{"class":800,"line":1363},[798,1778,1779],{"class":808},"    if",[798,1781,1782],{"class":804}," ($address ",[798,1784,1715],{"class":808},[798,1786,1718],{"class":815},[798,1788,1641],{"class":804},[798,1790,1791,1794,1796,1799,1801],{"class":800,"line":1376},[798,1792,1793],{"class":804},"      $country ",[798,1795,809],{"class":808},[798,1797,1798],{"class":804}," $address",[798,1800,827],{"class":808},[798,1802,1803],{"class":804},"country;\n",[798,1805,1806],{"class":800,"line":1382},[798,1807,947],{"class":804},[798,1809,1810],{"class":800,"line":1397},[798,1811,1428],{"class":804},[798,1813,1814],{"class":800,"line":1411},[798,1815,953],{"class":804},[25,1817,1818],{},"Dipersingkat jadi mirip seperti di bahasa pemrograman yang udah nerapin duluan kaya gini, ngirit source code banget sumpah dah hahaha",[790,1820,1822],{"className":792,"code":1821,"language":794,"meta":242,"style":242},"$country = $session?->user?->getAddress()?->country;\n",[703,1823,1824],{"__ignoreMap":242},[798,1825,1826,1828,1830,1832,1835,1838,1840,1842,1845,1847],{"class":800,"line":801},[798,1827,1693],{"class":804},[798,1829,809],{"class":808},[798,1831,1730],{"class":804},[798,1833,1834],{"class":808},"?->",[798,1836,1837],{"class":804},"user",[798,1839,1834],{"class":808},[798,1841,1768],{"class":854},[798,1843,1844],{"class":804},"()",[798,1846,1834],{"class":808},[798,1848,1803],{"class":804},[20,1850,1852],{"id":1851},"enumerations","Enumerations",[25,1854,1855],{},"Ini gokil sih, di php 8.1 ada kawan baru namanya enum cukup banget membantu buat mengecek kecocokan daripada harus pake instance class, nggak mudeng?? Nih perbangingannya",[790,1857,1859],{"className":792,"code":1858,"language":794,"meta":242,"style":242},"class Status\n{\n    const DRAFT = 'draft';\n    const PUBLISHED = 'published';\n    const ARCHIVED = 'archived';\n}\nfunction acceptStatus(string $status) {...}\n",[703,1860,1861,1868,1872,1888,1902,1916,1920],{"__ignoreMap":242},[798,1862,1863,1865],{"class":800,"line":801},[798,1864,787],{"class":808},[798,1866,1867],{"class":854}," Status\n",[798,1869,1870],{"class":800,"line":243},[798,1871,1210],{"class":804},[798,1873,1874,1877,1880,1883,1886],{"class":800,"line":251},[798,1875,1876],{"class":808},"    const",[798,1878,1879],{"class":815}," DRAFT",[798,1881,1882],{"class":808}," =",[798,1884,1885],{"class":835}," 'draft'",[798,1887,839],{"class":804},[798,1889,1890,1892,1895,1897,1900],{"class":800,"line":944},[798,1891,1876],{"class":808},[798,1893,1894],{"class":815}," PUBLISHED",[798,1896,1882],{"class":808},[798,1898,1899],{"class":835}," 'published'",[798,1901,839],{"class":804},[798,1903,1904,1906,1909,1911,1914],{"class":800,"line":950},[798,1905,1876],{"class":808},[798,1907,1908],{"class":815}," ARCHIVED",[798,1910,1882],{"class":808},[798,1912,1913],{"class":835}," 'archived'",[798,1915,839],{"class":804},[798,1917,1918],{"class":800,"line":956},[798,1919,953],{"class":804},[798,1921,1922,1925,1928,1930,1933,1936,1939],{"class":800,"line":962},[798,1923,1924],{"class":808},"function",[798,1926,1927],{"class":854}," acceptStatus",[798,1929,1221],{"class":804},[798,1931,1932],{"class":808},"string",[798,1934,1935],{"class":804}," $status) {",[798,1937,1938],{"class":808},"...",[798,1940,953],{"class":804},[790,1942,1944],{"className":792,"code":1943,"language":794,"meta":242,"style":242},"enum Status\n{\n    case Draft;\n    case Published;\n    case Archived;\n}\nfunction acceptStatus(Status $status) {...}\n",[703,1945,1946,1953,1957,1967,1976,1985,1989],{"__ignoreMap":242},[798,1947,1948,1951],{"class":800,"line":801},[798,1949,1950],{"class":808},"enum",[798,1952,1867],{"class":854},[798,1954,1955],{"class":800,"line":243},[798,1956,1210],{"class":804},[798,1958,1959,1962,1965],{"class":800,"line":251},[798,1960,1961],{"class":808},"    case",[798,1963,1964],{"class":815}," Draft",[798,1966,839],{"class":804},[798,1968,1969,1971,1974],{"class":800,"line":944},[798,1970,1961],{"class":808},[798,1972,1973],{"class":815}," Published",[798,1975,839],{"class":804},[798,1977,1978,1980,1983],{"class":800,"line":950},[798,1979,1961],{"class":808},[798,1981,1982],{"class":815}," Archived",[798,1984,839],{"class":804},[798,1986,1987],{"class":800,"line":956},[798,1988,953],{"class":804},[798,1990,1991,1993,1995,1997,2000,2002,2004],{"class":800,"line":962},[798,1992,1924],{"class":808},[798,1994,1927],{"class":854},[798,1996,1221],{"class":804},[798,1998,1999],{"class":815},"Status",[798,2001,1935],{"class":804},[798,2003,1938],{"class":808},[798,2005,953],{"class":804},[20,2007,2009],{"id":2008},"readonly-properties","Readonly Properties",[790,2011,2013],{"className":792,"code":2012,"language":794,"meta":242,"style":242},"class BlogData\n{\n    public readonly Status $status;\n\n    public function __construct(Status $status)\n    {\n        $this->status = $status;\n    }\n}\n",[703,2014,2015,2022,2026,2039,2043,2058,2063,2076,2080],{"__ignoreMap":242},[798,2016,2017,2019],{"class":800,"line":801},[798,2018,787],{"class":808},[798,2020,2021],{"class":854}," BlogData\n",[798,2023,2024],{"class":800,"line":243},[798,2025,1210],{"class":804},[798,2027,2028,2030,2033,2036],{"class":800,"line":251},[798,2029,916],{"class":808},[798,2031,2032],{"class":808}," readonly",[798,2034,2035],{"class":815}," Status",[798,2037,2038],{"class":804}," $status;\n",[798,2040,2041],{"class":800,"line":944},[798,2042,959],{"emptyLinePlaceholder":277},[798,2044,2045,2047,2049,2051,2053,2055],{"class":800,"line":950},[798,2046,916],{"class":808},[798,2048,919],{"class":808},[798,2050,922],{"class":815},[798,2052,1221],{"class":804},[798,2054,1999],{"class":815},[798,2056,2057],{"class":804}," $status)\n",[798,2059,2060],{"class":800,"line":956},[798,2061,2062],{"class":804},"    {\n",[798,2064,2065,2067,2069,2072,2074],{"class":800,"line":962},[798,2066,930],{"class":815},[798,2068,827],{"class":808},[798,2070,2071],{"class":804},"status ",[798,2073,809],{"class":808},[798,2075,2038],{"class":804},[798,2077,2078],{"class":800,"line":1349},[798,2079,947],{"class":804},[798,2081,2082],{"class":800,"line":1363},[798,2083,953],{"class":804},[25,2085,2086],{},"Yap kadang atau sering, ngga sengaja override property yang niatnya ngga bisa di apa-apain, bikin kesel kan?? Untung di versi 8.1 property bisa dijadikan readonly atau singkatnya property itu ngga bisa lagi dimodifikasi setelah di assign oleh constructor 👌",[20,2088,2090],{"id":2089},"pure-intersection-types","Pure Intersection Types",[25,2092,2093,2094,2097,2098,712,2101,2104,2105],{},"Setelah sebelumnya ada union types di versi 8 diperkenalkan, di 8.1 ada yang baru namanya Pure Intersection Types, apa sih? Ya dimana sebuah argument harus merupakan sebuah instance dari lebih dari satu constraints dalam satu waktu. Misalnya ",[703,2095,2096],{},"$value"," harus merupakan bagian dari ",[703,2099,2100],{},"Iterator",[703,2102,2103],{},"Countable"," , ngga boleh salah satu aja. Di versi 8 kebawah kita harus set dulu salah satu constraints baru kita cek dengan expression setelahnya, tapi cukup memakan waktu nah sekarang udah ngga lagi cukup gabungkan 2 constraints pake simbol",[703,2106,2107],{},"&",[790,2109,2111],{"className":792,"code":2110,"language":794,"meta":242,"style":242},"function count_and_iterate(Iterator&Countable $value) {\n    foreach ($value as $val) {\n        echo $val;\n    }\n\n    count($value);\n}\n",[703,2112,2113,2131,2145,2153,2157,2161,2169],{"__ignoreMap":242},[798,2114,2115,2117,2120,2122,2124,2126,2128],{"class":800,"line":801},[798,2116,1924],{"class":808},[798,2118,2119],{"class":854}," count_and_iterate",[798,2121,1221],{"class":804},[798,2123,2100],{"class":815},[798,2125,2107],{"class":804},[798,2127,2103],{"class":815},[798,2129,2130],{"class":804}," $value) {\n",[798,2132,2133,2136,2139,2142],{"class":800,"line":243},[798,2134,2135],{"class":808},"    foreach",[798,2137,2138],{"class":804}," ($value ",[798,2140,2141],{"class":808},"as",[798,2143,2144],{"class":804}," $val) {\n",[798,2146,2147,2150],{"class":800,"line":251},[798,2148,2149],{"class":815},"        echo",[798,2151,2152],{"class":804}," $val;\n",[798,2154,2155],{"class":800,"line":944},[798,2156,947],{"class":804},[798,2158,2159],{"class":800,"line":950},[798,2160,959],{"emptyLinePlaceholder":277},[798,2162,2163,2166],{"class":800,"line":956},[798,2164,2165],{"class":815},"    count",[798,2167,2168],{"class":804},"($value);\n",[798,2170,2171],{"class":800,"line":962},[798,2172,953],{"class":804},[20,2174,2176],{"id":2175},"itu-aja-sih-kalo-dariku","Itu aja sih kalo dariku",[25,2178,2179,2180,2183,2184,2187,2189],{},"Sebenernya ada banyak yang baru kaya ",[94,2181,2182],{},"Final class constants"," dan masih banyak lagi, cuma ngetiknya dah cape 😂😂😂😂. Ini bukti kalo komunitas PHP masih eksis dan mau bersaing dengan bahasa pemrograman lain utamanya web yang udah makin bejibun. Kalo penasaran bisa kunjungi dua link berikut ya...",[2185,2186],"br",{},[2185,2188],{},[75,2190,2191],{"href":2191,"rel":2192},"https:\u002F\u002Fwww.php.net\u002Freleases\u002F8.0\u002Fen.php",[79],[25,2194,2195],{},[75,2196,2197],{"href":2197,"rel":2198},"https:\u002F\u002Fwww.php.net\u002Freleases\u002F8.1\u002Fen.php",[79],[25,2200,2201],{},"Sekian dulu ya sob catatan gabut kali ini, sampai jumpa dan tetep belajar! FYI gw lagi nyobain NuxtJs 3, ada yang sama? Boleh sharing lewat telegram 👍🍵",[1093,2203,2204],{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":242,"searchDepth":243,"depth":243,"links":2206},[2207,2208,2209,2210,2211,2212,2213,2214,2215,2216],{"id":1120,"depth":243,"text":1121},{"id":1189,"depth":243,"text":1190},{"id":1264,"depth":243,"text":1265},{"id":1510,"depth":243,"text":1511},{"id":1609,"depth":243,"text":1610},{"id":1679,"depth":243,"text":1680},{"id":1851,"depth":243,"text":1852},{"id":2008,"depth":243,"text":2009},{"id":2089,"depth":243,"text":2090},{"id":2175,"depth":243,"text":2176},"2021-12-18","PHP 8, inovasi revolusioner si pak tua yang tak mau kalah sama yang lebih muda","\u002Fimages\u002Fblog\u002Fphp-8.png",{},"\u002Fblog\u002Fphp-8",{"title":1112,"description":2218},{"loc":2221},"blog\u002Fphp-8","5FOXAYTakL2O5t7kyzNCX2ObTolaKdqsoMlkJ3pcVn0",{"id":2227,"title":2228,"body":2229,"date":2440,"description":2441,"extension":274,"image":2442,"meta":2443,"navigation":277,"path":2444,"seo":2445,"sitemap":2446,"stem":2447,"__hash__":2448},"blog\u002Fblog\u002Fdebounce-apa-bedanya-dengan-throttle.md","Debounce – What's the difference with throttle?",{"type":17,"value":2230,"toc":2432},[2231,2242,2246,2253,2257,2260,2264,2267,2279,2293,2298,2387,2392,2396,2415,2419,2429],[25,2232,2233,2234,2237,2238,2241],{},"As a web developer, whether back-end or front-end, you’ve probably heard the term ",[94,2235,2236],{},"Throttle"," before, right? Simply put, throttle is used to limit the number of hits to an endpoint or application by a single user\u002Fclient within a certain period. For example, if we want to limit the ",[703,2239,2240],{},"api\u002Fuser"," endpoint to only be accessed 60 times per minute, we can use throttling technology. So, what is debounce?",[20,2243,2245],{"id":2244},"debounce","Debounce",[25,2247,2248,2249,2252],{},"Debounce literally means ",[29,2250,2251],{},"to bounce"," if you translate it with Google Translate, and that’s not far off. Debounce comes from an electronics concept, like a TV remote, where the remote only sends a signal when you’ve actually finished pressing a button. The concept is similar here.",[20,2254,2256],{"id":2255},"when-should-you-use-debounce","When should you use debounce?",[25,2258,2259],{},"Let me explain. As a good front-end developer, it’s best to maintain harmony between FE and BE developers, right? One way to do this is by using debounce. For example, suppose we want to create an input field that searches for a list of districts based on the keyword entered by the user. So, what should we do? Here’s a sample case.",[89,2261,2263],{"id":2262},"example-case","Example Case",[25,2265,2266],{},"An input field requires a minimum of 3 characters, and the system should hit the API when the user finishes typing, with a 100ms delay after the last input. So, how do we do this in JavaScript? Here’s how:",[597,2268,2269],{},[349,2270,2271,2272,327,2275,2278],{},"First, you need to set a global variable, either with ",[703,2273,2274],{},"var",[703,2276,2277],{},"let",", as needed.",[790,2280,2284],{"className":2281,"code":2282,"language":2283,"meta":242,"style":242},"language-js shiki shiki-themes github-light github-dark","let debounce\n","js",[703,2285,2286],{"__ignoreMap":242},[798,2287,2288,2290],{"class":800,"line":801},[798,2289,2277],{"class":808},[798,2291,2292],{"class":804}," debounce\n",[597,2294,2295],{"start":243},[349,2296,2297],{},"In the main trigger function (can be applied in the listener)",[790,2299,2301],{"className":2281,"code":2300,"language":2283,"meta":242,"style":242},"const onChange = () => {\n  if (debounce) {\n    clearTimeout(debounce)\n  }\n\n  debounce = setTimeout(() => {\n    fetch('some_stuff')\n  }, 100)\n}\n",[703,2302,2303,2320,2327,2335,2339,2343,2360,2373,2383],{"__ignoreMap":242},[798,2304,2305,2307,2310,2312,2315,2318],{"class":800,"line":801},[798,2306,759],{"class":808},[798,2308,2309],{"class":854}," onChange",[798,2311,1882],{"class":808},[798,2313,2314],{"class":804}," () ",[798,2316,2317],{"class":808},"=>",[798,2319,911],{"class":804},[798,2321,2322,2324],{"class":800,"line":243},[798,2323,1744],{"class":808},[798,2325,2326],{"class":804}," (debounce) {\n",[798,2328,2329,2332],{"class":800,"line":251},[798,2330,2331],{"class":854},"    clearTimeout",[798,2333,2334],{"class":804},"(debounce)\n",[798,2336,2337],{"class":800,"line":944},[798,2338,1428],{"class":804},[798,2340,2341],{"class":800,"line":950},[798,2342,959],{"emptyLinePlaceholder":277},[798,2344,2345,2348,2350,2353,2356,2358],{"class":800,"line":956},[798,2346,2347],{"class":804},"  debounce ",[798,2349,809],{"class":808},[798,2351,2352],{"class":854}," setTimeout",[798,2354,2355],{"class":804},"(() ",[798,2357,2317],{"class":808},[798,2359,911],{"class":804},[798,2361,2362,2365,2367,2370],{"class":800,"line":962},[798,2363,2364],{"class":854},"    fetch",[798,2366,1221],{"class":804},[798,2368,2369],{"class":835},"'some_stuff'",[798,2371,2372],{"class":804},")\n",[798,2374,2375,2378,2381],{"class":800,"line":1349},[798,2376,2377],{"class":804},"  }, ",[798,2379,2380],{"class":815},"100",[798,2382,2372],{"class":804},[798,2384,2385],{"class":800,"line":1363},[798,2386,953],{"class":804},[597,2388,2389],{"start":251},[349,2390,2391],{},"Yep, that's it—simple, right? Okay, let's break it down.",[89,2393,2395],{"id":2394},"explanation","Explanation",[597,2397,2398,2401,2408],{},[349,2399,2400],{},"First, we need to set a variable to hold the timeout function.",[349,2402,2403,2404,2407],{},"We always need to check if the variable already has a value; if it does, use the ",[703,2405,2406],{},"clearTimeout"," function to remove the queued delay.",[349,2409,2410,2411,2414],{},"Now, just fill the variable again. If there are no more changes, the variable won't be cleared, so ",[703,2412,2413],{},"fetch"," (the main function) will automatically be triggered.",[20,2416,2418],{"id":2417},"debounce-vs-throttle","Debounce vs Throttle",[25,2420,2421,2422,2424,2425,2428],{},"Short and sweet, right? It's not hard to prevent things like flood caused by front-end apps—just start by using ",[29,2423,2244],{},". But that doesn't mean you should ignore ",[29,2426,2427],{},"throttle","; you still need both to keep things in sync. So that's a simple article from me, thanks for reading and see you in the next post.",[1093,2430,2431],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":242,"searchDepth":243,"depth":243,"links":2433},[2434,2435,2439],{"id":2244,"depth":243,"text":2245},{"id":2255,"depth":243,"text":2256,"children":2436},[2437,2438],{"id":2262,"depth":251,"text":2263},{"id":2394,"depth":251,"text":2395},{"id":2417,"depth":243,"text":2418},"0202-06-10","Debounce means delaying the execution of a repeatedly called function until there is an idle condition within a specified time range.","\u002Fimages\u002Fblog\u002Fdebounce.png",{},"\u002Fblog\u002Fdebounce-apa-bedanya-dengan-throttle",{"title":2228,"description":2441},{"loc":2444},"blog\u002Fdebounce-apa-bedanya-dengan-throttle","uBmMtvdDCCa1Vhi5eWjUFvVw3_Tg8nQ9oxkvf9Jv7Zc",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2450},"\u003Cg fill=\"none\">\u003Cpath stroke=\"currentColor\" stroke-width=\"1.5\" d=\"M2 12c0-3.771 0-5.657 1.172-6.828S6.229 4 10 4h4c3.771 0 5.657 0 6.828 1.172S22 8.229 22 12v2c0 3.771 0 5.657-1.172 6.828S17.771 22 14 22h-4c-3.771 0-5.657 0-6.828-1.172S2 17.771 2 14z\"\u002F>\u003Cpath stroke=\"currentColor\" stroke-linecap=\"round\" stroke-width=\"1.5\" d=\"M7 4V2.5M17 4V2.5M2.5 9h19\"\u002F>\u003Cpath fill=\"currentColor\" d=\"M18 17a1 1 0 1 1-2 0a1 1 0 0 1 2 0m0-4a1 1 0 1 1-2 0a1 1 0 0 1 2 0m-5 4a1 1 0 1 1-2 0a1 1 0 0 1 2 0m0-4a1 1 0 1 1-2 0a1 1 0 0 1 2 0m-5 4a1 1 0 1 1-2 0a1 1 0 0 1 2 0m0-4a1 1 0 1 1-2 0a1 1 0 0 1 2 0\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":2452},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M8 12h8m0 0l-3-3m3 3l-3 3\"\u002F>\u003C\u002Fg>",1779378197369]