[{"data":1,"prerenderedAt":2960},["ShallowReactive",2],{"cv-nav":3,"blog-posts":131},{"id":4,"title":5,"avatar":6,"education":7,"email":19,"experience":20,"extension":68,"github":69,"linkedin":70,"location":71,"meta":72,"name":73,"skills":74,"stem":126,"summary":127,"tagline":128,"twitter":129,"__hash__":130},"cv\u002Fcv.json","Senior Software Engineer","\u002Favatar.jpg",[8,12,16],{"institution":9,"degree":10,"year":11},"Multimedia University of Kenya","Bachelor of Science — Mathematics and Computer Science (Pure Mathematics)","Graduated",{"institution":13,"degree":14,"year":15},"eMobilis","Mobile Software Development and Entrepreneurship Program","Completed",{"institution":17,"degree":18,"year":15},"Sundoulos African Leadership Training (SALT)","Servant Leadership","waweruj00@gmail.com",[21,30,40,50,60],{"company":22,"role":5,"period":23,"description":24,"highlights":25},"Kalvad","October 2018 – Present","Worldwide Tech Agency solving business problems through cutting-edge technology.",[26,27,28,29],"Design, develop and deploy frontend applications for clients using Angular and Vue.js as primary technologies.","Write Node.js Lambda functions for heavy browser computations and deploy them to AWS using the Serverless Framework.","Write GitHub Actions configurations and dockerize frontend apps for deployment to Coolify.","Work with project leads to plan implementation of functional requirements and collaborate with clients on UI design.",{"company":31,"role":5,"period":32,"description":33,"highlights":34},"Finsweet (Wized)","May 2022 – February 2024","Full-stack engineer on Wized — a no-code platform enabling Webflow developers to build data-rich apps.",[35,36,37,38,39],"Built data integrations to Firebase, Supabase, Notion, Xano, Airtable, Stripe, and REST APIs.","Enabled authentication and user management for Webflow apps via the Wized platform.","Worked on the Wized Embed library — DOM integration layer powering page actions without custom JavaScript.","Built the configurator tool for developers to manage projects, workspaces and app configuration.","Supported Stripe Connected Apps for payment collection and transaction fee processing.",{"company":41,"role":42,"period":43,"description":44,"highlights":45},"CanGo (formerly Safemotos)","Backend Software Engineer","June 2019 – February 2020","On-demand transportation and food delivery service (similar to Bolt\u002FUber).",[46,47,48,49],"Built microservices using NestJS for a GraphQL API serving mobile and web clients.","Developed Payment, Trip Management, Events Controller, and Customer Management services.","Created an internal Apache Kafka library with Avro schema management for producers and consumers.","Designed microservice architecture with the CTO and deployed to Kubernetes monitored via Prometheus and Grafana.",{"company":51,"role":52,"period":53,"description":54,"highlights":55},"Middleware Inc.","Backend Software Engineer (Consultant)","April 2020 – August 2020","Fleet management company. Responsible for a Node.js microservice called Bloodhound.",[56,57,58,59],"Built fleet tracking system consuming IoT data relayed by Golang microservices on motorcycles.","Implemented driver management including motor vehicle assignment.","Built motor vehicle management covering road worthiness and insurance tracking.","Developed a REST API serving dashboard data to the frontend team. MongoDB as the database.",{"company":61,"role":62,"period":63,"description":64,"highlights":65},"LivingGoods","Software Engineer, Consultant","May 2018 – May 2019","NGO supporting digitally empowered community health workers. Started as intern, promoted to consultant.",[66,67],"Maintained an SMS Health Information System built with Python and RapidSMS.","Created and maintained an ETL tool streaming data to and from the SMS platform for dashboard observability.","json","https:\u002F\u002Fgithub.com\u002Fwaw3ru","https:\u002F\u002Flinkedin.com\u002Fin\u002Fwaw3ru","Nairobi, Kenya",{},"John (.W.) Wambugu",[75,82,92,102,108,116],{"category":76,"skills":77},"Programming Languages",[78,79,80,81],"JavaScript","Typescript","Golang","Python",{"category":83,"skills":84},"Frontend",[85,86,87,88,89,90,91],"Angular","Vue","Preact","Vite","Nuxt","Tailwind CSS","UI Design",{"category":93,"skills":94},"Backend",[95,96,97,98,99,100,101],"Node.js - but I use Bun 😊","NestJS","Flask","Hono","Gin","Fiber","Django",{"category":103,"skills":104},"DevOps",[105,106,107],"Docker","Kubernetes","Coolify",{"category":109,"skills":110},"Databases",[111,112,113,114,115],"PostgreSQL","MongoDB","SQLite","Redis","Apache Kafka",{"category":117,"skills":118},"Tools",[119,120,121,122,123,124,125],"n8n","Firebase","Supabase","Git","Travis CI","Gitlab CI","GitHub Actions","cv","Senior Software Engineer with a deep-rooted passion for TypeScript, Angular, Vue.js, Node.js and Python. Over 7 years honing my craft across agencies, startups, NGOs and consultancies — from microservices and distributed systems to no-code platforms and frontend applications.","Maestro in web development. 8+ years building robust, efficient, and user-centric software solutions.","https:\u002F\u002Fx.com\u002Fwaw3ru","vxrx4fMa1gNDENkmVi8SXWwRH4_KnHx8Uj-ELWNfqPQ",[132,1498],{"id":133,"title":134,"body":135,"category":1483,"cover":1484,"description":1485,"extension":1486,"meta":1487,"navigation":248,"path":1488,"publishedAt":1489,"seo":1490,"stem":1491,"tags":1492,"__hash__":1497},"blog\u002Fblog\u002Fwhen-error-i-defer-golang-than-typescript-nodejs-implied.md","When in an error, I defer to Golang than Typescript (node.js implied 😉)",{"type":136,"value":137,"toc":1481},"minimark",[138,142,145,148,363,369,376,379,382,510,513,699,702,709,1262,1265,1333,1336,1434,1437,1440,1474,1477],[139,140,141],"p",{},"Typescript is an elegant programming language with the best developer experience. One aspect about Typescript that most engineers overlook is it's a type system not \"a programming language\". To back up my claim, I would say without JavaScript there is no Typescript but without Typescript we still have JavaScript. Some engineers can go further and claim that JsDocs can be used in place of Typescript.",[139,143,144],{},"Now that doesn't mean you can't bypass that whole noise of Typescript being just a type system. If you look at deno and bun (JavaScript runtimes), the language of choice is Typescript. Although behind the scenes what actually runs is JavaScript, you don't need to worry about setting up tsconfig.json and compiling your _.ts files to _.js so that you can eventually run your code. Those runtimes do that for you; hence, TypeScript is a language from their standpoint.",[139,146,147],{},"Case in point, this is what bun init command outputs when you are starting setting up your project",[149,150,155],"pre",{"className":151,"code":152,"language":153,"meta":154,"style":154},"language-bash shiki shiki-themes dark-plus material-theme nord","$ bun init\nbun init helps you get started with a minimal project and tries to\nguess sensible defaults. Press ^C anytime to quit.\n\npackage name (quickstart):\nentry point (index.ts):\n\nDone! A package.json file was saved in the current directory.\n\n- index.ts\n- .gitignore\n- tsconfig.json (for editor auto-complete)\n- README.md\n","bash","",[156,157,158,174,216,243,250,263,275,280,313,318,327,335,355],"code",{"__ignoreMap":154},[159,160,163,167,171],"span",{"class":161,"line":162},"line",1,[159,164,166],{"class":165},"sIqb1","$",[159,168,170],{"class":169},"sVhVX"," bun",[159,172,173],{"class":169}," init\n",[159,175,177,180,183,186,189,192,195,198,201,204,207,210,213],{"class":161,"line":176},2,[159,178,179],{"class":165},"bun",[159,181,182],{"class":169}," init",[159,184,185],{"class":169}," helps",[159,187,188],{"class":169}," you",[159,190,191],{"class":169}," get",[159,193,194],{"class":169}," started",[159,196,197],{"class":169}," with",[159,199,200],{"class":169}," a",[159,202,203],{"class":169}," minimal",[159,205,206],{"class":169}," project",[159,208,209],{"class":169}," and",[159,211,212],{"class":169}," tries",[159,214,215],{"class":169}," to\n",[159,217,219,222,225,228,231,234,237,240],{"class":161,"line":218},3,[159,220,221],{"class":165},"guess",[159,223,224],{"class":169}," sensible",[159,226,227],{"class":169}," defaults.",[159,229,230],{"class":169}," Press",[159,232,233],{"class":169}," ^C",[159,235,236],{"class":169}," anytime",[159,238,239],{"class":169}," to",[159,241,242],{"class":169}," quit.\n",[159,244,246],{"class":161,"line":245},4,[159,247,249],{"emptyLinePlaceholder":248},true,"\n",[159,251,253,256,259],{"class":161,"line":252},5,[159,254,255],{"class":165},"package",[159,257,258],{"class":169}," name",[159,260,262],{"class":261},"sU6aI"," (quickstart):\n",[159,264,266,269,272],{"class":161,"line":265},6,[159,267,268],{"class":165},"entry",[159,270,271],{"class":169}," point",[159,273,274],{"class":261}," (index.ts):\n",[159,276,278],{"class":161,"line":277},7,[159,279,249],{"emptyLinePlaceholder":248},[159,281,283,286,289,292,295,298,301,304,307,310],{"class":161,"line":282},8,[159,284,285],{"class":165},"Done!",[159,287,288],{"class":169}," A",[159,290,291],{"class":169}," package.json",[159,293,294],{"class":169}," file",[159,296,297],{"class":169}," was",[159,299,300],{"class":169}," saved",[159,302,303],{"class":169}," in",[159,305,306],{"class":169}," the",[159,308,309],{"class":169}," current",[159,311,312],{"class":169}," directory.\n",[159,314,316],{"class":161,"line":315},9,[159,317,249],{"emptyLinePlaceholder":248},[159,319,321,324],{"class":161,"line":320},10,[159,322,323],{"class":165},"-",[159,325,326],{"class":169}," index.ts\n",[159,328,330,332],{"class":161,"line":329},11,[159,331,323],{"class":165},[159,333,334],{"class":169}," .gitignore\n",[159,336,338,340,343,346,349,352],{"class":161,"line":337},12,[159,339,323],{"class":165},[159,341,342],{"class":169}," tsconfig.json",[159,344,345],{"class":261}," (for ",[159,347,348],{"class":169},"editor",[159,350,351],{"class":169}," auto-complete",[159,353,354],{"class":261},")\n",[159,356,358,360],{"class":161,"line":357},13,[159,359,323],{"class":165},[159,361,362],{"class":169}," README.md\n",[139,364,365,366],{},"To get started, run: ",[156,367,368],{},"$ bun run index.ts",[139,370,371,372,375],{},"They generate ",[156,373,374],{},"tsconfig.json"," for your editor but you run your Typescript code directly.",[139,377,378],{},"Back to the topic at hand\nI recently fell in love with Golang. The simplicity that runtimes like bun bring is built into the ecosystem of Golang. In this article, we will look into Golang's error handling. I am not a pro in Golang, but in my journey of learning the language I got to appreciate how it represents its concepts and lexical approaches.",[139,380,381],{},"The elegance of error handling in Golang\nThe old way we do, try me and I'll catch you seems to be the best approach. But of late it seems to be a horror. TypeScript's way of throwing errors is:",[149,383,388],{"className":384,"code":385,"filename":386,"language":387,"meta":154,"style":154},"language-typescript shiki shiki-themes dark-plus material-theme nord","function myAlwaysError() {\n    const d: string = \"\";\n    if (d.length \u003C 1) throw new Error(\"Why me!!\");\n    return \"It's me!\";\n}\n","always-errors.ts","typescript",[156,389,390,407,434,490,505],{"__ignoreMap":154},[159,391,392,396,400,404],{"class":161,"line":162},[159,393,395],{"class":394},"s90zX","function",[159,397,399],{"class":398},"sb-48"," myAlwaysError",[159,401,403],{"class":402},"s1Uiq","()",[159,405,406],{"class":402}," {\n",[159,408,409,412,416,420,424,427,431],{"class":161,"line":176},[159,410,411],{"class":394},"    const",[159,413,415],{"class":414},"sYz0q"," d",[159,417,419],{"class":418},"skl-N",":",[159,421,423],{"class":422},"snyXp"," string",[159,425,426],{"class":418}," =",[159,428,430],{"class":429},"s7myh"," \"\"",[159,432,433],{"class":418},";\n",[159,435,436,440,444,448,451,454,457,461,464,467,471,474,477,480,483,485,488],{"class":161,"line":218},[159,437,439],{"class":438},"sq_UV","    if",[159,441,443],{"class":442},"syouj"," (",[159,445,447],{"class":446},"sRv_x","d",[159,449,450],{"class":402},".",[159,452,453],{"class":446},"length",[159,455,456],{"class":418}," \u003C",[159,458,460],{"class":459},"sqUOZ"," 1",[159,462,463],{"class":442},") ",[159,465,466],{"class":438},"throw",[159,468,470],{"class":469},"s11Tq"," new",[159,472,473],{"class":398}," Error",[159,475,476],{"class":442},"(",[159,478,479],{"class":429},"\"",[159,481,482],{"class":169},"Why me!!",[159,484,479],{"class":429},[159,486,487],{"class":442},")",[159,489,433],{"class":418},[159,491,492,495,498,501,503],{"class":161,"line":245},[159,493,494],{"class":438},"    return",[159,496,497],{"class":429}," \"",[159,499,500],{"class":169},"It's me!",[159,502,479],{"class":429},[159,504,433],{"class":418},[159,506,507],{"class":161,"line":252},[159,508,509],{"class":402},"}\n",[139,511,512],{},"It's perfect! You know it's a string so no need to worry about the type of constant d. You are the one throwing an error so still in your mindset of how the program is expected to run, you can have ~100% correctness. If I don't want my program to panic while I implement your function, I have no choice but to play cat ... mouse with your function.",[149,514,517],{"className":384,"code":515,"filename":516,"language":387,"meta":154,"style":154},"function myAlwaysError() {\n  const D: string = \"\";\n  if (D.length \u003C 1) throw new Error(\"Why me!!\");\n  return \"It's me!\";\n}\n\nfunction main() {\n  try {\n    const hello = myAlwaysError();\n  } catch (e) {\n    console.error(e);\n  }\n}\n\nmain();\n","main.ts",[156,518,519,529,547,585,598,602,606,617,624,639,657,675,680,684,689],{"__ignoreMap":154},[159,520,521,523,525,527],{"class":161,"line":162},[159,522,395],{"class":394},[159,524,399],{"class":398},[159,526,403],{"class":402},[159,528,406],{"class":402},[159,530,531,534,537,539,541,543,545],{"class":161,"line":176},[159,532,533],{"class":394},"  const",[159,535,536],{"class":414}," D",[159,538,419],{"class":418},[159,540,423],{"class":422},[159,542,426],{"class":418},[159,544,430],{"class":429},[159,546,433],{"class":418},[159,548,549,552,554,557,559,561,563,565,567,569,571,573,575,577,579,581,583],{"class":161,"line":218},[159,550,551],{"class":438},"  if",[159,553,443],{"class":442},[159,555,556],{"class":414},"D",[159,558,450],{"class":402},[159,560,453],{"class":446},[159,562,456],{"class":418},[159,564,460],{"class":459},[159,566,463],{"class":442},[159,568,466],{"class":438},[159,570,470],{"class":469},[159,572,473],{"class":398},[159,574,476],{"class":442},[159,576,479],{"class":429},[159,578,482],{"class":169},[159,580,479],{"class":429},[159,582,487],{"class":442},[159,584,433],{"class":418},[159,586,587,590,592,594,596],{"class":161,"line":245},[159,588,589],{"class":438},"  return",[159,591,497],{"class":429},[159,593,500],{"class":169},[159,595,479],{"class":429},[159,597,433],{"class":418},[159,599,600],{"class":161,"line":252},[159,601,509],{"class":402},[159,603,604],{"class":161,"line":265},[159,605,249],{"emptyLinePlaceholder":248},[159,607,608,610,613,615],{"class":161,"line":277},[159,609,395],{"class":394},[159,611,612],{"class":398}," main",[159,614,403],{"class":402},[159,616,406],{"class":402},[159,618,619,622],{"class":161,"line":282},[159,620,621],{"class":438},"  try",[159,623,406],{"class":402},[159,625,626,628,631,633,635,637],{"class":161,"line":315},[159,627,411],{"class":394},[159,629,630],{"class":414}," hello",[159,632,426],{"class":418},[159,634,399],{"class":398},[159,636,403],{"class":442},[159,638,433],{"class":418},[159,640,641,644,647,649,652,654],{"class":161,"line":320},[159,642,643],{"class":402},"  }",[159,645,646],{"class":438}," catch",[159,648,443],{"class":442},[159,650,651],{"class":446},"e",[159,653,463],{"class":442},[159,655,656],{"class":402},"{\n",[159,658,659,662,664,667,669,671,673],{"class":161,"line":329},[159,660,661],{"class":446},"    console",[159,663,450],{"class":402},[159,665,666],{"class":398},"error",[159,668,476],{"class":442},[159,670,651],{"class":446},[159,672,487],{"class":442},[159,674,433],{"class":418},[159,676,677],{"class":161,"line":337},[159,678,679],{"class":402},"  }\n",[159,681,682],{"class":161,"line":357},[159,683,509],{"class":402},[159,685,687],{"class":161,"line":686},14,[159,688,249],{"emptyLinePlaceholder":248},[159,690,692,695,697],{"class":161,"line":691},15,[159,693,694],{"class":398},"main",[159,696,403],{"class":261},[159,698,433],{"class":418},[139,700,701],{},"The above code example is a pain because of the following:",[139,703,704,705,708],{},"The error argument e is scoped. This means I have to squeeze all my error handling computation and functionality inside the block or assign it to a global variable.\nI cannot use any variable I declared within the try block when I am done with handling my mistakes (errors). Unless I let, above my ",[156,706,707],{},"try ... catch",". See the example below",[149,710,714],{"className":711,"code":712,"filename":386,"language":713,"meta":154,"style":154},"language-ts shiki shiki-themes dark-plus material-theme nord","function myAlwaysError() {\n    const D: string = \"\";\n    if (D.length \u003C 1) throw new Error(\"Why me!!\");\n    return \"It's me!\";\n}\n\ntype MainReturnType = \"error\" | \"text\";\n\ntype BaseReturn = {\n    type: MainReturnType;\n    functionCalled: string;\n};\n\ntype MainReturn = BaseReturn & (\n    { type: \"error\"; errorMessage: string; } |\n    { type: \"text\"; message: string; }\n);\n\nfunction main(): MainReturn {\n    let type: MainReturnType;\n    let message: string;\n    try {\n        const hello = myAlwaysError();\n        type = \"text\"\n        message = hello;\n    } catch (e: Error) {\n        type = \"error\";\n        message = e.message\n    }\n\n    if (type === \"text\") {\n        return {\n            type: \"text\",\n            functionCalled: \"myAlwaysError\",\n            message,\n        };\n    }\n\n    return {\n        type:\n        message,\n        functionCalled: \"myAlwaysError\"\n    };\n}\n","ts",[156,715,716,726,742,778,790,794,798,826,830,841,853,864,871,875,892,926,955,962,967,982,996,1009,1017,1033,1048,1060,1081,1096,1111,1117,1122,1144,1152,1171,1188,1196,1204,1209,1214,1221,1229,1236,1250,1257],{"__ignoreMap":154},[159,717,718,720,722,724],{"class":161,"line":162},[159,719,395],{"class":394},[159,721,399],{"class":398},[159,723,403],{"class":402},[159,725,406],{"class":402},[159,727,728,730,732,734,736,738,740],{"class":161,"line":176},[159,729,411],{"class":394},[159,731,536],{"class":414},[159,733,419],{"class":418},[159,735,423],{"class":422},[159,737,426],{"class":418},[159,739,430],{"class":429},[159,741,433],{"class":418},[159,743,744,746,748,750,752,754,756,758,760,762,764,766,768,770,772,774,776],{"class":161,"line":218},[159,745,439],{"class":438},[159,747,443],{"class":442},[159,749,556],{"class":414},[159,751,450],{"class":402},[159,753,453],{"class":446},[159,755,456],{"class":418},[159,757,460],{"class":459},[159,759,463],{"class":442},[159,761,466],{"class":438},[159,763,470],{"class":469},[159,765,473],{"class":398},[159,767,476],{"class":442},[159,769,479],{"class":429},[159,771,482],{"class":169},[159,773,479],{"class":429},[159,775,487],{"class":442},[159,777,433],{"class":418},[159,779,780,782,784,786,788],{"class":161,"line":245},[159,781,494],{"class":438},[159,783,497],{"class":429},[159,785,500],{"class":169},[159,787,479],{"class":429},[159,789,433],{"class":418},[159,791,792],{"class":161,"line":252},[159,793,509],{"class":402},[159,795,796],{"class":161,"line":265},[159,797,249],{"emptyLinePlaceholder":248},[159,799,800,803,806,808,810,812,814,817,819,822,824],{"class":161,"line":277},[159,801,802],{"class":394},"type",[159,804,805],{"class":422}," MainReturnType",[159,807,426],{"class":418},[159,809,497],{"class":429},[159,811,666],{"class":169},[159,813,479],{"class":429},[159,815,816],{"class":418}," |",[159,818,497],{"class":429},[159,820,821],{"class":169},"text",[159,823,479],{"class":429},[159,825,433],{"class":418},[159,827,828],{"class":161,"line":282},[159,829,249],{"emptyLinePlaceholder":248},[159,831,832,834,837,839],{"class":161,"line":315},[159,833,802],{"class":394},[159,835,836],{"class":422}," BaseReturn",[159,838,426],{"class":418},[159,840,406],{"class":402},[159,842,843,847,849,851],{"class":161,"line":320},[159,844,846],{"class":845},"sPhFD","    type",[159,848,419],{"class":418},[159,850,805],{"class":422},[159,852,433],{"class":418},[159,854,855,858,860,862],{"class":161,"line":329},[159,856,857],{"class":845},"    functionCalled",[159,859,419],{"class":418},[159,861,423],{"class":422},[159,863,433],{"class":418},[159,865,866,869],{"class":161,"line":337},[159,867,868],{"class":402},"}",[159,870,433],{"class":418},[159,872,873],{"class":161,"line":357},[159,874,249],{"emptyLinePlaceholder":248},[159,876,877,879,882,884,886,889],{"class":161,"line":686},[159,878,802],{"class":394},[159,880,881],{"class":422}," MainReturn",[159,883,426],{"class":418},[159,885,836],{"class":422},[159,887,888],{"class":418}," &",[159,890,891],{"class":261}," (\n",[159,893,894,897,900,902,904,906,908,911,914,916,918,920,923],{"class":161,"line":691},[159,895,896],{"class":402},"    {",[159,898,899],{"class":845}," type",[159,901,419],{"class":418},[159,903,497],{"class":429},[159,905,666],{"class":169},[159,907,479],{"class":429},[159,909,910],{"class":418},";",[159,912,913],{"class":845}," errorMessage",[159,915,419],{"class":418},[159,917,423],{"class":422},[159,919,910],{"class":418},[159,921,922],{"class":402}," }",[159,924,925],{"class":418}," |\n",[159,927,929,931,933,935,937,939,941,943,946,948,950,952],{"class":161,"line":928},16,[159,930,896],{"class":402},[159,932,899],{"class":845},[159,934,419],{"class":418},[159,936,497],{"class":429},[159,938,821],{"class":169},[159,940,479],{"class":429},[159,942,910],{"class":418},[159,944,945],{"class":845}," message",[159,947,419],{"class":418},[159,949,423],{"class":422},[159,951,910],{"class":418},[159,953,954],{"class":402}," }\n",[159,956,958,960],{"class":161,"line":957},17,[159,959,487],{"class":261},[159,961,433],{"class":418},[159,963,965],{"class":161,"line":964},18,[159,966,249],{"emptyLinePlaceholder":248},[159,968,970,972,974,976,978,980],{"class":161,"line":969},19,[159,971,395],{"class":394},[159,973,612],{"class":398},[159,975,403],{"class":402},[159,977,419],{"class":418},[159,979,881],{"class":422},[159,981,406],{"class":402},[159,983,985,988,990,992,994],{"class":161,"line":984},20,[159,986,987],{"class":394},"    let",[159,989,899],{"class":446},[159,991,419],{"class":418},[159,993,805],{"class":422},[159,995,433],{"class":418},[159,997,999,1001,1003,1005,1007],{"class":161,"line":998},21,[159,1000,987],{"class":394},[159,1002,945],{"class":446},[159,1004,419],{"class":418},[159,1006,423],{"class":422},[159,1008,433],{"class":418},[159,1010,1012,1015],{"class":161,"line":1011},22,[159,1013,1014],{"class":438},"    try",[159,1016,406],{"class":402},[159,1018,1020,1023,1025,1027,1029,1031],{"class":161,"line":1019},23,[159,1021,1022],{"class":394},"        const",[159,1024,630],{"class":414},[159,1026,426],{"class":418},[159,1028,399],{"class":398},[159,1030,403],{"class":442},[159,1032,433],{"class":418},[159,1034,1036,1039,1041,1043,1045],{"class":161,"line":1035},24,[159,1037,1038],{"class":446},"        type",[159,1040,426],{"class":418},[159,1042,497],{"class":429},[159,1044,821],{"class":169},[159,1046,1047],{"class":429},"\"\n",[159,1049,1051,1054,1056,1058],{"class":161,"line":1050},25,[159,1052,1053],{"class":446},"        message",[159,1055,426],{"class":418},[159,1057,630],{"class":446},[159,1059,433],{"class":418},[159,1061,1063,1066,1068,1070,1073,1075,1077,1079],{"class":161,"line":1062},26,[159,1064,1065],{"class":402},"    }",[159,1067,646],{"class":438},[159,1069,443],{"class":402},[159,1071,651],{"class":1072},"sQrig",[159,1074,419],{"class":418},[159,1076,473],{"class":422},[159,1078,487],{"class":402},[159,1080,406],{"class":402},[159,1082,1084,1086,1088,1090,1092,1094],{"class":161,"line":1083},27,[159,1085,1038],{"class":446},[159,1087,426],{"class":418},[159,1089,497],{"class":429},[159,1091,666],{"class":169},[159,1093,479],{"class":429},[159,1095,433],{"class":418},[159,1097,1099,1101,1103,1106,1108],{"class":161,"line":1098},28,[159,1100,1053],{"class":446},[159,1102,426],{"class":418},[159,1104,1105],{"class":446}," e",[159,1107,450],{"class":402},[159,1109,1110],{"class":446},"message\n",[159,1112,1114],{"class":161,"line":1113},29,[159,1115,1116],{"class":402},"    }\n",[159,1118,1120],{"class":161,"line":1119},30,[159,1121,249],{"emptyLinePlaceholder":248},[159,1123,1125,1127,1129,1131,1134,1136,1138,1140,1142],{"class":161,"line":1124},31,[159,1126,439],{"class":438},[159,1128,443],{"class":442},[159,1130,802],{"class":446},[159,1132,1133],{"class":418}," ===",[159,1135,497],{"class":429},[159,1137,821],{"class":169},[159,1139,479],{"class":429},[159,1141,463],{"class":442},[159,1143,656],{"class":402},[159,1145,1147,1150],{"class":161,"line":1146},32,[159,1148,1149],{"class":438},"        return",[159,1151,406],{"class":402},[159,1153,1155,1159,1162,1164,1166,1168],{"class":161,"line":1154},33,[159,1156,1158],{"class":1157},"sZDzJ","            type",[159,1160,419],{"class":1161},"sA8ib",[159,1163,497],{"class":429},[159,1165,821],{"class":169},[159,1167,479],{"class":429},[159,1169,1170],{"class":402},",\n",[159,1172,1174,1177,1179,1181,1184,1186],{"class":161,"line":1173},34,[159,1175,1176],{"class":1157},"            functionCalled",[159,1178,419],{"class":1161},[159,1180,497],{"class":429},[159,1182,1183],{"class":169},"myAlwaysError",[159,1185,479],{"class":429},[159,1187,1170],{"class":402},[159,1189,1191,1194],{"class":161,"line":1190},35,[159,1192,1193],{"class":446},"            message",[159,1195,1170],{"class":402},[159,1197,1199,1202],{"class":161,"line":1198},36,[159,1200,1201],{"class":402},"        }",[159,1203,433],{"class":418},[159,1205,1207],{"class":161,"line":1206},37,[159,1208,1116],{"class":402},[159,1210,1212],{"class":161,"line":1211},38,[159,1213,249],{"emptyLinePlaceholder":248},[159,1215,1217,1219],{"class":161,"line":1216},39,[159,1218,494],{"class":438},[159,1220,406],{"class":402},[159,1222,1224,1226],{"class":161,"line":1223},40,[159,1225,1038],{"class":1157},[159,1227,1228],{"class":1161},":\n",[159,1230,1232,1234],{"class":161,"line":1231},41,[159,1233,1053],{"class":446},[159,1235,1170],{"class":402},[159,1237,1239,1242,1244,1246,1248],{"class":161,"line":1238},42,[159,1240,1241],{"class":1157},"        functionCalled",[159,1243,419],{"class":1161},[159,1245,497],{"class":429},[159,1247,1183],{"class":169},[159,1249,1047],{"class":429},[159,1251,1253,1255],{"class":161,"line":1252},43,[159,1254,1065],{"class":402},[159,1256,433],{"class":418},[159,1258,1260],{"class":161,"line":1259},44,[159,1261,509],{"class":402},[139,1263,1264],{},"Now, what I love about Golang is errors are passed as values. This means I handle my errors like I do my variables. A simple approach to Golang error handling will be this",[149,1266,1271],{"className":1267,"code":1268,"filename":1269,"language":1270,"meta":154,"style":154},"language-go shiki shiki-themes dark-plus material-theme nord","package main\n\nimport (\n    \"errors\"\n    \"fmt\"\n)\n\nfunc checkMyArgument(arg int) (int, error) {\n    if arg == 19 {\n        return 0, errors.New(\"You missed my guess 😜!\")\n    }\n    return arg * 7, nil\n}\n","main.go","go",[156,1272,1273,1278,1282,1287,1292,1297,1301,1305,1310,1315,1320,1324,1329],{"__ignoreMap":154},[159,1274,1275],{"class":161,"line":162},[159,1276,1277],{},"package main\n",[159,1279,1280],{"class":161,"line":176},[159,1281,249],{"emptyLinePlaceholder":248},[159,1283,1284],{"class":161,"line":218},[159,1285,1286],{},"import (\n",[159,1288,1289],{"class":161,"line":245},[159,1290,1291],{},"    \"errors\"\n",[159,1293,1294],{"class":161,"line":252},[159,1295,1296],{},"    \"fmt\"\n",[159,1298,1299],{"class":161,"line":265},[159,1300,354],{},[159,1302,1303],{"class":161,"line":277},[159,1304,249],{"emptyLinePlaceholder":248},[159,1306,1307],{"class":161,"line":282},[159,1308,1309],{},"func checkMyArgument(arg int) (int, error) {\n",[159,1311,1312],{"class":161,"line":315},[159,1313,1314],{},"    if arg == 19 {\n",[159,1316,1317],{"class":161,"line":320},[159,1318,1319],{},"        return 0, errors.New(\"You missed my guess 😜!\")\n",[159,1321,1322],{"class":161,"line":329},[159,1323,1116],{},[159,1325,1326],{"class":161,"line":337},[159,1327,1328],{},"    return arg * 7, nil\n",[159,1330,1331],{"class":161,"line":357},[159,1332,509],{},[139,1334,1335],{},"Now the syntax is a bit different but you can see a \"tuple-like\" approach to returning values. This is because when calling the function, you get to do this:",[149,1337,1339],{"className":1267,"code":1338,"filename":1269,"language":1270,"meta":154,"style":154},"import (\n    \"errors\"\n    \"fmt\"\n)\n\nfunc checkMyArgument(arg int) (int, error) {\n    if arg == 42 {\n        return -1, errors.New(\"can't work with 42 nor Types...42\")\n    }\n    return arg + 3, nil\n}\n\nfunc main() {\n    argument, err := checkMyArgument(90)\n\n    if err == nil {\n        fmt.Println(\"I failed you!:\", err)\n    } else {\n        fmt.Println(\"Look at me now!:\", argument)\n    }\n}\n",[156,1340,1341,1345,1349,1353,1357,1361,1365,1370,1375,1379,1384,1388,1392,1397,1402,1406,1411,1416,1421,1426,1430],{"__ignoreMap":154},[159,1342,1343],{"class":161,"line":162},[159,1344,1286],{},[159,1346,1347],{"class":161,"line":176},[159,1348,1291],{},[159,1350,1351],{"class":161,"line":218},[159,1352,1296],{},[159,1354,1355],{"class":161,"line":245},[159,1356,354],{},[159,1358,1359],{"class":161,"line":252},[159,1360,249],{"emptyLinePlaceholder":248},[159,1362,1363],{"class":161,"line":265},[159,1364,1309],{},[159,1366,1367],{"class":161,"line":277},[159,1368,1369],{},"    if arg == 42 {\n",[159,1371,1372],{"class":161,"line":282},[159,1373,1374],{},"        return -1, errors.New(\"can't work with 42 nor Types...42\")\n",[159,1376,1377],{"class":161,"line":315},[159,1378,1116],{},[159,1380,1381],{"class":161,"line":320},[159,1382,1383],{},"    return arg + 3, nil\n",[159,1385,1386],{"class":161,"line":329},[159,1387,509],{},[159,1389,1390],{"class":161,"line":337},[159,1391,249],{"emptyLinePlaceholder":248},[159,1393,1394],{"class":161,"line":357},[159,1395,1396],{},"func main() {\n",[159,1398,1399],{"class":161,"line":686},[159,1400,1401],{},"    argument, err := checkMyArgument(90)\n",[159,1403,1404],{"class":161,"line":691},[159,1405,249],{"emptyLinePlaceholder":248},[159,1407,1408],{"class":161,"line":928},[159,1409,1410],{},"    if err == nil {\n",[159,1412,1413],{"class":161,"line":957},[159,1414,1415],{},"        fmt.Println(\"I failed you!:\", err)\n",[159,1417,1418],{"class":161,"line":964},[159,1419,1420],{},"    } else {\n",[159,1422,1423],{"class":161,"line":969},[159,1424,1425],{},"        fmt.Println(\"Look at me now!:\", argument)\n",[159,1427,1428],{"class":161,"line":984},[159,1429,1116],{},[159,1431,1432],{"class":161,"line":998},[159,1433,509],{},[139,1435,1436],{},"I hope you can spot the difference.",[139,1438,1439],{},"I don't need to reassign the error to some other variable because it's passed as a value or in layman's terms; as a returned value. So, the scope or lifetime of a variable does not hinder you from doing what's right by the errors you experience.\nYou can make the whole thing short and clean.",[149,1441,1443],{"className":1267,"code":1442,"filename":1269,"language":1270,"meta":154,"style":154},"func main() {\n    if argument, err := checkMyArgument(90); err != nil {\n        fmt.Println(\"I failed you!:\", err)\n    } else {\n        fmt.Println(\"Look at me now!:\", argument)\n    }\n}\n",[156,1444,1445,1449,1454,1458,1462,1466,1470],{"__ignoreMap":154},[159,1446,1447],{"class":161,"line":162},[159,1448,1396],{},[159,1450,1451],{"class":161,"line":176},[159,1452,1453],{},"    if argument, err := checkMyArgument(90); err != nil {\n",[159,1455,1456],{"class":161,"line":218},[159,1457,1415],{},[159,1459,1460],{"class":161,"line":245},[159,1461,1420],{},[159,1463,1464],{"class":161,"line":252},[159,1465,1425],{},[159,1467,1468],{"class":161,"line":265},[159,1469,1116],{},[159,1471,1472],{"class":161,"line":277},[159,1473,509],{},[139,1475,1476],{},"My take on why Golang handles errors better\nThe aim of this article was to give a perspective on how at a language level developer-friendliness is important. If you are to work on a fault-tolerant application. Your team would benefit if they could handle the errors thrown by various parts of the system as returned values. The robustness of Typescript is fun when it comes to type definition but types are not everything, the developer experience of the actual code that runs is still something the JS community should consider and work on improving. As I end my hot-take on who's handling errors better, I know the TS\u002FJS community can come up with an even innovative way of handling errors. I hope this article made you get interested in learning Golang. It's the best alternative for Typescript developers, in my view. Happy coding, take care!",[1478,1479,1480],"style",{},"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 .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sIqb1, html code.shiki .sIqb1{--shiki-default:#DCDCAA;--shiki-dark:#FFCB6B;--shiki-sepia:#88C0D0}html pre.shiki code .sVhVX, html code.shiki .sVhVX{--shiki-default:#CE9178;--shiki-dark:#C3E88D;--shiki-sepia:#A3BE8C}html pre.shiki code .sU6aI, html code.shiki .sU6aI{--shiki-default:#D4D4D4;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9FF}html pre.shiki code .s90zX, html code.shiki .s90zX{--shiki-default:#569CD6;--shiki-dark:#C792EA;--shiki-sepia:#81A1C1}html pre.shiki code .sb-48, html code.shiki .sb-48{--shiki-default:#DCDCAA;--shiki-dark:#82AAFF;--shiki-sepia:#88C0D0}html pre.shiki code .s1Uiq, html code.shiki .s1Uiq{--shiki-default:#D4D4D4;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}html pre.shiki code .sYz0q, html code.shiki .sYz0q{--shiki-default:#4FC1FF;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9}html pre.shiki code .skl-N, html code.shiki .skl-N{--shiki-default:#D4D4D4;--shiki-dark:#89DDFF;--shiki-sepia:#81A1C1}html pre.shiki code .snyXp, html code.shiki .snyXp{--shiki-default:#4EC9B0;--shiki-dark:#FFCB6B;--shiki-sepia:#8FBCBB}html pre.shiki code .s7myh, html code.shiki .s7myh{--shiki-default:#CE9178;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}html pre.shiki code .sq_UV, html code.shiki .sq_UV{--shiki-default:#C586C0;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;--shiki-sepia:#81A1C1;--shiki-sepia-font-style:inherit}html pre.shiki code .syouj, html code.shiki .syouj{--shiki-default:#D4D4D4;--shiki-dark:#F07178;--shiki-sepia:#D8DEE9FF}html pre.shiki code .sRv_x, html code.shiki .sRv_x{--shiki-default:#9CDCFE;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9}html pre.shiki code .sqUOZ, html code.shiki .sqUOZ{--shiki-default:#B5CEA8;--shiki-dark:#F78C6C;--shiki-sepia:#B48EAD}html pre.shiki code .s11Tq, html code.shiki .s11Tq{--shiki-default:#569CD6;--shiki-dark:#89DDFF;--shiki-sepia:#81A1C1}html pre.shiki code .sPhFD, html code.shiki .sPhFD{--shiki-default:#9CDCFE;--shiki-dark:#F07178;--shiki-sepia:#D8DEE9FF}html pre.shiki code .sQrig, html code.shiki .sQrig{--shiki-default:#9CDCFE;--shiki-default-font-style:inherit;--shiki-dark:#EEFFFF;--shiki-dark-font-style:italic;--shiki-sepia:#D8DEE9;--shiki-sepia-font-style:inherit}html pre.shiki code .sZDzJ, html code.shiki .sZDzJ{--shiki-default:#9CDCFE;--shiki-dark:#F07178;--shiki-sepia:#D8DEE9}html pre.shiki code .sA8ib, html code.shiki .sA8ib{--shiki-default:#9CDCFE;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}",{"title":154,"searchDepth":176,"depth":176,"links":1482},[],"Sofware Engineering","\u002Frahul-mishra-Zs5X1KnHUzw-unsplash-1.jpg","An argument that Go’s explicit error handling and defer statement offer superior reliability compared to the implicit try\u002Fcatch patterns in TypeScript\u002FNode.js. While Go’s if err != nil approach is more verbose, it treats errors as first-class values, forcing developers to handle failures immediately. This reduces mental overhead' and prevents the silent failures or unhandled promises common in complex, asynchronous Node.js environments.","md",{},"\u002Fblog\u002Fwhen-error-i-defer-golang-than-typescript-nodejs-implied","2023-11-10",{"title":134,"description":1485},"blog\u002Fwhen-error-i-defer-golang-than-typescript-nodejs-implied",[1493,79,1494,1495,1496],"Go","Node.js","Bun","Error Handling","lq6D2X0zKj4yaw22_o_9bgowROeGMAXr57e0qRm-rBk",{"id":1499,"title":1500,"body":1501,"category":2948,"cover":2949,"description":2950,"extension":1486,"meta":2951,"navigation":248,"path":2952,"publishedAt":2953,"seo":2954,"stem":2955,"tags":2956,"__hash__":2959},"blog\u002Fblog\u002Futilizing-weakmap-to-effectively-store-metadata.md","Utilizing WeakMap to effectively store Metadata file",{"type":136,"value":1502,"toc":2942},[1503,1507,1523,1531,1737,1740,1747,1821,1841,1848,1880,2214,2220,2232,2268,2281,2401,2443,2446,2452,2458,2461,2507,2510,2613,2621,2837,2868,2874,2880,2919,2936,2939],[1504,1505,1500],"h1",{"id":1506},"utilizing-weakmap-to-effectively-store-metadata-file",[139,1508,1509,1510,1515,1519,1520],{},"Metadata is simply data that holds information about some other piece of data. Seems repetitive but if you were to think of networking and mainly HTTP. If you perform an HTTP request, data is sent or received (HTTP response) together with some HTTP headers. The HTTP headers are considered metadata and specifically ",[159,1511],{"className":1512,"style":1514},[1513],"white-space-pre","box-sizing: inherit; margin: 0px; padding: 0px; border-color: rgba(255, 255, 255, 0.9); border-style: none; border-width: 0px; border-image: none 100% \u002F 1 \u002F 0 stretch; font-size: 16px; vertical-align: baseline; background: none 0% 0% \u002F auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); outline: rgba(255, 255, 255, 0.9) none 0px; white-space: pre !important; font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Fira Sans\", Ubuntu, Oxygen, \"Oxygen Sans\", Cantarell, \"Droid Sans\", \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Lucida Grande\", Helvetica, Arial, sans-serif;",[1516,1517,1518],"em",{},"descriptive metadata",". So as much as you as the recipient of the request might want to read the data sent, you will need the HTTP headers to be able to understand the data you have been sent. ",[159,1521],{"className":1522,"style":1514},[1513],[139,1524,1525,1526,1530],{},"This caught my interest because most of the time, when I am creating a web application. I would want my, let say ",[1527,1528,1529],"strong",{},"DOM"," elements, to hold some information (metadata). I don't want to mutate them by adding attributes so the most obvious way I thought of, is to use a cache object. An example of a cache object would be",[149,1532,1536],{"className":1533,"code":1534,"language":1535,"meta":154,"style":154},"language-js shiki shiki-themes dark-plus material-theme nord","const cache = {};\n\ncache[\"user1\"] = {\n    object: new User(\"admin\"),\n    meta: {\n        syncedOn: new Date(\"2009-11-27T16:45:30\"),\n    }\n};\n\ncache[\"user2\"] = {\n    object: new User(\"student\"),\n    meta: {\n        syncedOn: new Date(\"2009-11-27T09:45:30\"),\n    }\n};\n","js",[156,1537,1538,1553,1557,1580,1606,1615,1640,1644,1650,1654,1673,1696,1704,1727,1731],{"__ignoreMap":154},[159,1539,1540,1543,1546,1548,1551],{"class":161,"line":162},[159,1541,1542],{"class":394},"const",[159,1544,1545],{"class":414}," cache",[159,1547,426],{"class":418},[159,1549,1550],{"class":402}," {}",[159,1552,433],{"class":418},[159,1554,1555],{"class":161,"line":176},[159,1556,249],{"emptyLinePlaceholder":248},[159,1558,1559,1562,1565,1567,1570,1572,1575,1578],{"class":161,"line":218},[159,1560,1561],{"class":446},"cache",[159,1563,1564],{"class":261},"[",[159,1566,479],{"class":429},[159,1568,1569],{"class":169},"user1",[159,1571,479],{"class":429},[159,1573,1574],{"class":261},"] ",[159,1576,1577],{"class":418},"=",[159,1579,406],{"class":402},[159,1581,1582,1586,1588,1590,1593,1595,1597,1600,1602,1604],{"class":161,"line":245},[159,1583,1585],{"class":1584},"sgyjr","    object",[159,1587,419],{"class":1161},[159,1589,470],{"class":469},[159,1591,1592],{"class":398}," User",[159,1594,476],{"class":261},[159,1596,479],{"class":429},[159,1598,1599],{"class":169},"admin",[159,1601,479],{"class":429},[159,1603,487],{"class":261},[159,1605,1170],{"class":402},[159,1607,1608,1611,1613],{"class":161,"line":252},[159,1609,1610],{"class":1584},"    meta",[159,1612,419],{"class":1161},[159,1614,406],{"class":402},[159,1616,1617,1620,1622,1624,1627,1629,1631,1634,1636,1638],{"class":161,"line":265},[159,1618,1619],{"class":1584},"        syncedOn",[159,1621,419],{"class":1161},[159,1623,470],{"class":469},[159,1625,1626],{"class":398}," Date",[159,1628,476],{"class":261},[159,1630,479],{"class":429},[159,1632,1633],{"class":169},"2009-11-27T16:45:30",[159,1635,479],{"class":429},[159,1637,487],{"class":261},[159,1639,1170],{"class":402},[159,1641,1642],{"class":161,"line":277},[159,1643,1116],{"class":402},[159,1645,1646,1648],{"class":161,"line":282},[159,1647,868],{"class":402},[159,1649,433],{"class":418},[159,1651,1652],{"class":161,"line":315},[159,1653,249],{"emptyLinePlaceholder":248},[159,1655,1656,1658,1660,1662,1665,1667,1669,1671],{"class":161,"line":320},[159,1657,1561],{"class":446},[159,1659,1564],{"class":261},[159,1661,479],{"class":429},[159,1663,1664],{"class":169},"user2",[159,1666,479],{"class":429},[159,1668,1574],{"class":261},[159,1670,1577],{"class":418},[159,1672,406],{"class":402},[159,1674,1675,1677,1679,1681,1683,1685,1687,1690,1692,1694],{"class":161,"line":329},[159,1676,1585],{"class":1584},[159,1678,419],{"class":1161},[159,1680,470],{"class":469},[159,1682,1592],{"class":398},[159,1684,476],{"class":261},[159,1686,479],{"class":429},[159,1688,1689],{"class":169},"student",[159,1691,479],{"class":429},[159,1693,487],{"class":261},[159,1695,1170],{"class":402},[159,1697,1698,1700,1702],{"class":161,"line":337},[159,1699,1610],{"class":1584},[159,1701,419],{"class":1161},[159,1703,406],{"class":402},[159,1705,1706,1708,1710,1712,1714,1716,1718,1721,1723,1725],{"class":161,"line":357},[159,1707,1619],{"class":1584},[159,1709,419],{"class":1161},[159,1711,470],{"class":469},[159,1713,1626],{"class":398},[159,1715,476],{"class":261},[159,1717,479],{"class":429},[159,1719,1720],{"class":169},"2009-11-27T09:45:30",[159,1722,479],{"class":429},[159,1724,487],{"class":261},[159,1726,1170],{"class":402},[159,1728,1729],{"class":161,"line":686},[159,1730,1116],{"class":402},[159,1732,1733,1735],{"class":161,"line":691},[159,1734,868],{"class":402},[159,1736,433],{"class":418},[139,1738,1739],{},"Some problems with the example above are:",[1741,1742,1743],"ul",{},[1744,1745,1746],"li",{},"Iteration can be a pain",[149,1748,1750],{"className":1533,"code":1749,"language":1535,"meta":154,"style":154},"for (const key in cache) {\n    \u002F\u002F check all users whose last sync were 20 minutes ago\n}\n\n\u002F\u002F OR\nObject.keys(cache).map(someComputationBasedOnMetadata);\n",[156,1751,1752,1772,1778,1782,1786,1791],{"__ignoreMap":154},[159,1753,1754,1757,1759,1761,1764,1766,1768,1770],{"class":161,"line":162},[159,1755,1756],{"class":438},"for",[159,1758,443],{"class":261},[159,1760,1542],{"class":394},[159,1762,1763],{"class":414}," key",[159,1765,303],{"class":469},[159,1767,1545],{"class":446},[159,1769,463],{"class":261},[159,1771,656],{"class":402},[159,1773,1774],{"class":161,"line":176},[159,1775,1777],{"class":1776},"sNvoV","    \u002F\u002F check all users whose last sync were 20 minutes ago\n",[159,1779,1780],{"class":161,"line":218},[159,1781,509],{"class":402},[159,1783,1784],{"class":161,"line":245},[159,1785,249],{"emptyLinePlaceholder":248},[159,1787,1788],{"class":161,"line":252},[159,1789,1790],{"class":1776},"\u002F\u002F OR\n",[159,1792,1793,1796,1798,1801,1803,1805,1807,1809,1812,1814,1817,1819],{"class":161,"line":265},[159,1794,1795],{"class":446},"Object",[159,1797,450],{"class":402},[159,1799,1800],{"class":398},"keys",[159,1802,476],{"class":261},[159,1804,1561],{"class":446},[159,1806,487],{"class":261},[159,1808,450],{"class":402},[159,1810,1811],{"class":398},"map",[159,1813,476],{"class":261},[159,1815,1816],{"class":446},"someComputationBasedOnMetadata",[159,1818,487],{"class":261},[159,1820,433],{"class":418},[1741,1822,1823],{},[1744,1824,1825,1826,1829,1831,1834,1835,1838,450],{},"If ",[159,1827],{"className":1828,"style":1514},[1513],[1516,1830,1664],{},[159,1832],{"className":1833,"style":1514},[1513]," is no longer used it won't be garbage collected since there is still a lingering reference to it. This causes ",[159,1836],{"className":1837,"style":1514},[1513],[1527,1839,1840],{},"memory leaks",[1842,1843,1845],"h2",{"id":1844},"solving-iteration-in-javascript",[1527,1846,1847],{},"Solving iteration in JavaScript",[139,1849,1850,1851,1854,1859,1862,1863,1866,1869,1870,1873,1876,1879],{},"In JavaScript, we can make an object to behave like an Array by adding ",[159,1852],{"className":1853,"style":1514},[1513],[1516,1855,1856],{},[1527,1857,1858],{},"Symbol.iterator",[159,1860],{"className":1861,"style":1514},[1513],"  ",[1516,1864,1865],{},"generator function",[159,1867],{"className":1868,"style":1514},[1513]," which ",[159,1871],{"className":1872,"style":1514},[1513],[156,1874,1875],{},"yield",[159,1877],{"className":1878,"style":1514},[1513]," the values required",[149,1881,1883],{"className":1533,"code":1882,"language":1535,"meta":154,"style":154},"const cache = {\n    *[Symbol.iterator]() {\n      for (const k of Object.keys(this)) {\n             \u002F\u002F you could do more computation\n          yield this[k];\n      }\n    }\n};\n\ncache[\"john_doe\"] = {\n    object: new User(\"admin\"),\n    meta: {\n        syncedOn: new Date(\"2024-05-07T00:45:30\")\n    }\n};\n\ncache[\"jane_doe\"] = {\n    object: new User(\"root\"),\n    meta: {\n        syncedOn: new Date(\"2024-05-07T03:15:30\")\n    }\n};\n\nfor (const key of Object.keys(cache)) {\n        const metadata = cache[key];\n    \u002F\u002F some computation done here!\n}\n",[156,1884,1885,1895,1917,1949,1954,1971,1976,1980,1986,1990,2009,2031,2039,2060,2064,2070,2074,2093,2116,2124,2145,2149,2155,2159,2185,2205,2210],{"__ignoreMap":154},[159,1886,1887,1889,1891,1893],{"class":161,"line":162},[159,1888,1542],{"class":394},[159,1890,1545],{"class":414},[159,1892,426],{"class":418},[159,1894,406],{"class":402},[159,1896,1897,1900,1902,1905,1907,1910,1913,1915],{"class":161,"line":176},[159,1898,1899],{"class":469},"    *",[159,1901,1564],{"class":261},[159,1903,1904],{"class":446},"Symbol",[159,1906,450],{"class":402},[159,1908,1909],{"class":446},"iterator",[159,1911,1912],{"class":261},"]",[159,1914,403],{"class":402},[159,1916,406],{"class":402},[159,1918,1919,1922,1924,1926,1929,1932,1935,1937,1939,1941,1944,1947],{"class":161,"line":218},[159,1920,1921],{"class":438},"      for",[159,1923,443],{"class":442},[159,1925,1542],{"class":394},[159,1927,1928],{"class":414}," k",[159,1930,1931],{"class":469}," of",[159,1933,1934],{"class":446}," Object",[159,1936,450],{"class":402},[159,1938,1800],{"class":398},[159,1940,476],{"class":442},[159,1942,1943],{"class":469},"this",[159,1945,1946],{"class":442},")) ",[159,1948,656],{"class":402},[159,1950,1951],{"class":161,"line":245},[159,1952,1953],{"class":1776},"             \u002F\u002F you could do more computation\n",[159,1955,1956,1959,1962,1964,1967,1969],{"class":161,"line":252},[159,1957,1958],{"class":438},"          yield",[159,1960,1961],{"class":469}," this",[159,1963,1564],{"class":442},[159,1965,1966],{"class":446},"k",[159,1968,1912],{"class":442},[159,1970,433],{"class":418},[159,1972,1973],{"class":161,"line":265},[159,1974,1975],{"class":402},"      }\n",[159,1977,1978],{"class":161,"line":277},[159,1979,1116],{"class":402},[159,1981,1982,1984],{"class":161,"line":282},[159,1983,868],{"class":402},[159,1985,433],{"class":418},[159,1987,1988],{"class":161,"line":315},[159,1989,249],{"emptyLinePlaceholder":248},[159,1991,1992,1994,1996,1998,2001,2003,2005,2007],{"class":161,"line":320},[159,1993,1561],{"class":446},[159,1995,1564],{"class":261},[159,1997,479],{"class":429},[159,1999,2000],{"class":169},"john_doe",[159,2002,479],{"class":429},[159,2004,1574],{"class":261},[159,2006,1577],{"class":418},[159,2008,406],{"class":402},[159,2010,2011,2013,2015,2017,2019,2021,2023,2025,2027,2029],{"class":161,"line":329},[159,2012,1585],{"class":1584},[159,2014,419],{"class":1161},[159,2016,470],{"class":469},[159,2018,1592],{"class":398},[159,2020,476],{"class":261},[159,2022,479],{"class":429},[159,2024,1599],{"class":169},[159,2026,479],{"class":429},[159,2028,487],{"class":261},[159,2030,1170],{"class":402},[159,2032,2033,2035,2037],{"class":161,"line":337},[159,2034,1610],{"class":1584},[159,2036,419],{"class":1161},[159,2038,406],{"class":402},[159,2040,2041,2043,2045,2047,2049,2051,2053,2056,2058],{"class":161,"line":357},[159,2042,1619],{"class":1584},[159,2044,419],{"class":1161},[159,2046,470],{"class":469},[159,2048,1626],{"class":398},[159,2050,476],{"class":261},[159,2052,479],{"class":429},[159,2054,2055],{"class":169},"2024-05-07T00:45:30",[159,2057,479],{"class":429},[159,2059,354],{"class":261},[159,2061,2062],{"class":161,"line":686},[159,2063,1116],{"class":402},[159,2065,2066,2068],{"class":161,"line":691},[159,2067,868],{"class":402},[159,2069,433],{"class":418},[159,2071,2072],{"class":161,"line":928},[159,2073,249],{"emptyLinePlaceholder":248},[159,2075,2076,2078,2080,2082,2085,2087,2089,2091],{"class":161,"line":957},[159,2077,1561],{"class":446},[159,2079,1564],{"class":261},[159,2081,479],{"class":429},[159,2083,2084],{"class":169},"jane_doe",[159,2086,479],{"class":429},[159,2088,1574],{"class":261},[159,2090,1577],{"class":418},[159,2092,406],{"class":402},[159,2094,2095,2097,2099,2101,2103,2105,2107,2110,2112,2114],{"class":161,"line":964},[159,2096,1585],{"class":1584},[159,2098,419],{"class":1161},[159,2100,470],{"class":469},[159,2102,1592],{"class":398},[159,2104,476],{"class":261},[159,2106,479],{"class":429},[159,2108,2109],{"class":169},"root",[159,2111,479],{"class":429},[159,2113,487],{"class":261},[159,2115,1170],{"class":402},[159,2117,2118,2120,2122],{"class":161,"line":969},[159,2119,1610],{"class":1584},[159,2121,419],{"class":1161},[159,2123,406],{"class":402},[159,2125,2126,2128,2130,2132,2134,2136,2138,2141,2143],{"class":161,"line":984},[159,2127,1619],{"class":1584},[159,2129,419],{"class":1161},[159,2131,470],{"class":469},[159,2133,1626],{"class":398},[159,2135,476],{"class":261},[159,2137,479],{"class":429},[159,2139,2140],{"class":169},"2024-05-07T03:15:30",[159,2142,479],{"class":429},[159,2144,354],{"class":261},[159,2146,2147],{"class":161,"line":998},[159,2148,1116],{"class":402},[159,2150,2151,2153],{"class":161,"line":1011},[159,2152,868],{"class":402},[159,2154,433],{"class":418},[159,2156,2157],{"class":161,"line":1019},[159,2158,249],{"emptyLinePlaceholder":248},[159,2160,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181,2183],{"class":161,"line":1035},[159,2162,1756],{"class":438},[159,2164,443],{"class":261},[159,2166,1542],{"class":394},[159,2168,1763],{"class":414},[159,2170,1931],{"class":469},[159,2172,1934],{"class":446},[159,2174,450],{"class":402},[159,2176,1800],{"class":398},[159,2178,476],{"class":261},[159,2180,1561],{"class":446},[159,2182,1946],{"class":261},[159,2184,656],{"class":402},[159,2186,2187,2189,2192,2194,2196,2198,2201,2203],{"class":161,"line":1050},[159,2188,1022],{"class":394},[159,2190,2191],{"class":414}," metadata",[159,2193,426],{"class":418},[159,2195,1545],{"class":446},[159,2197,1564],{"class":442},[159,2199,2200],{"class":446},"key",[159,2202,1912],{"class":442},[159,2204,433],{"class":418},[159,2206,2207],{"class":161,"line":1062},[159,2208,2209],{"class":1776},"    \u002F\u002F some computation done here!\n",[159,2211,2212],{"class":161,"line":1083},[159,2213,509],{"class":402},[1842,2215,2217],{"id":2216},"managing-garbage-collection",[1527,2218,2219],{},"Managing garbage collection",[139,2221,2222,2223,2226,2229],{},"Here is where a tradeoff comes in. We are going to introduce a JavaScript data structure ",[159,2224],{"className":2225,"style":1514},[1513],[1527,2227,2228],{},"WeakMap.",[159,2230],{"className":2231,"style":1514},[1513],[139,2233,2234,2235,2238,2248,2250,2251,2254,2255,2258,2259,2258,2262,2264,2265],{},"A WeakMap is a collection of key\u002Fvalue pairs where the key is an object or ",[159,2236],{"className":2237,"style":1514},[1513],[1527,2239,2240],{},[2241,2242,2247],"a",{"href":2243,"rel":2244,"target":2246},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FSymbol#shared_symbols_in_the_global_symbol_registry",[2245],"nofollow","_self","non-registered symbol",[159,2249],{},"  and ",[1527,2252,2253],{},"the values are normal (or arbitrary) JavaScript types"," e.g. ",[1516,2256,2257],{},"Boolean"," or ",[1516,2260,2261],{},"Number",[1516,2263,78],{}," objects (). ",[159,2266],{"className":2267,"style":1514},[1513],[139,2269,2270,2271,2274,2277,2280],{},"Although it has a similar API to a ",[159,2272],{"className":2273,"style":1514},[1513],[1527,2275,2276],{},"Map",[159,2278],{"className":2279,"style":1514},[1513]," it has one main advantage which is the keys provided are never restricted from being garbage collected. This means:",[149,2282,2284],{"className":1533,"code":2283,"language":1535,"meta":154,"style":154},"const wm = new WeakMap();\nconst signupForm = document.querySelector(\"form[data-purpose='signup']\");\n\nwm.set(\n    signupForm, \n    { \n        lastFilledOn: new Date(\"2024-05-09T13:05:00\") \n    }\n);\n",[156,2285,2286,2304,2334,2338,2351,2362,2368,2391,2395],{"__ignoreMap":154},[159,2287,2288,2290,2293,2295,2297,2300,2302],{"class":161,"line":162},[159,2289,1542],{"class":394},[159,2291,2292],{"class":414}," wm",[159,2294,426],{"class":418},[159,2296,470],{"class":469},[159,2298,2299],{"class":398}," WeakMap",[159,2301,403],{"class":261},[159,2303,433],{"class":418},[159,2305,2306,2308,2311,2313,2316,2318,2321,2323,2325,2328,2330,2332],{"class":161,"line":176},[159,2307,1542],{"class":394},[159,2309,2310],{"class":414}," signupForm",[159,2312,426],{"class":418},[159,2314,2315],{"class":446}," document",[159,2317,450],{"class":402},[159,2319,2320],{"class":398},"querySelector",[159,2322,476],{"class":261},[159,2324,479],{"class":429},[159,2326,2327],{"class":169},"form[data-purpose='signup']",[159,2329,479],{"class":429},[159,2331,487],{"class":261},[159,2333,433],{"class":418},[159,2335,2336],{"class":161,"line":218},[159,2337,249],{"emptyLinePlaceholder":248},[159,2339,2340,2343,2345,2348],{"class":161,"line":245},[159,2341,2342],{"class":446},"wm",[159,2344,450],{"class":402},[159,2346,2347],{"class":398},"set",[159,2349,2350],{"class":261},"(\n",[159,2352,2353,2356,2359],{"class":161,"line":252},[159,2354,2355],{"class":446},"    signupForm",[159,2357,2358],{"class":402},",",[159,2360,2361],{"class":261}," \n",[159,2363,2364,2366],{"class":161,"line":265},[159,2365,896],{"class":402},[159,2367,2361],{"class":261},[159,2369,2370,2373,2375,2377,2379,2381,2383,2386,2388],{"class":161,"line":277},[159,2371,2372],{"class":1584},"        lastFilledOn",[159,2374,419],{"class":1161},[159,2376,470],{"class":469},[159,2378,1626],{"class":398},[159,2380,476],{"class":261},[159,2382,479],{"class":429},[159,2384,2385],{"class":169},"2024-05-09T13:05:00",[159,2387,479],{"class":429},[159,2389,2390],{"class":261},") \n",[159,2392,2393],{"class":161,"line":282},[159,2394,1116],{"class":402},[159,2396,2397,2399],{"class":161,"line":315},[159,2398,487],{"class":261},[159,2400,433],{"class":418},[2402,2403,2404],"blockquote",{},[139,2405,2406,2407,2411,2416,2419,2420,2423,2428,2431,2432,2435,2440],{},"In an event where ",[159,2408],{"className":2409,"style":2410},[1513],"box-sizing: inherit; margin: 0px; padding: 0px; border-color: rgb(158, 181, 202); border-style: none; border-width: 0px; border-image: none 100% \u002F 1 \u002F 0 stretch; font-size: 20px; vertical-align: baseline; background: none 0% 0% \u002F auto repeat scroll padding-box border-box rgba(0, 0, 0, 0); outline: rgb(158, 181, 202) none 0px; white-space: pre !important; font-family: -apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", \"Fira Sans\", Ubuntu, Oxygen, \"Oxygen Sans\", Cantarell, \"Droid Sans\", \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Lucida Grande\", Helvetica, Arial, sans-serif;",[1516,2412,2413],{},[1527,2414,2415],{},"signupForm",[159,2417],{"className":2418,"style":2410},[1513]," is no longer referenced, it will be garbage collected. This means later on ",[159,2421],{"className":2422,"style":2410},[1513],[1516,2424,2425],{},[1527,2426,2427],{},"wm.has(signupForm)",[159,2429],{"className":2430,"style":2410},[1513]," is returns ",[159,2433],{"className":2434,"style":2410},[1513],[1516,2436,2437],{},[1527,2438,2439],{},"false.",[159,2441],{"className":2442,"style":2410},[1513],[139,2444,2445],{},"Now the tradeoff is we cannot iterate over a WeakMap. The reason is because unlike Maps, WeakMaps do not keep an array or list of keys since its keys are non-deterministic or garbage collectable.",[1842,2447,2449],{"id":2448},"weakmap-use-case",[1527,2450,2451],{},"WeakMap use case",[139,2453,2454,2455],{},"Going back to our cache example, we can expand it by assuming a real-world use case. ",[159,2456],{"className":2457,"style":1514},[1513],[139,2459,2460],{},"Let's say we have a table of company employees. We are tasked to improve the table's functionality by enabling in-memory editing. We can cache the state of our form per row using WeakMap following the pattern.",[149,2462,2464],{"className":1533,"code":2463,"language":1535,"meta":154,"style":154},"type EditFormCache = WeakMap\u003CHTMLFormElement, \"editing\" | \"stalled\">;\n",[156,2465,2466],{"__ignoreMap":154},[159,2467,2468,2470,2474,2476,2478,2481,2484,2486,2488,2491,2493,2495,2497,2500,2502,2505],{"class":161,"line":162},[159,2469,802],{"class":394},[159,2471,2473],{"class":2472},"swHrb"," EditFormCache",[159,2475,426],{"class":418},[159,2477,2299],{"class":2472},[159,2479,2480],{"class":402},"\u003C",[159,2482,2483],{"class":2472},"HTMLFormElement",[159,2485,2358],{"class":402},[159,2487,497],{"class":429},[159,2489,2490],{"class":169},"editing",[159,2492,479],{"class":429},[159,2494,816],{"class":418},[159,2496,497],{"class":429},[159,2498,2499],{"class":169},"stalled",[159,2501,479],{"class":429},[159,2503,2504],{"class":402},">",[159,2506,433],{"class":418},[139,2508,2509],{},"This way when we toggle back and forth between a normal table row and a form row, we can only get forms which have not yet been garbage collected stored in our cache.",[149,2511,2513],{"className":1533,"code":2512,"language":1535,"meta":154,"style":154},"const wm = new WeakMap();\nconst form = document.querySelectorAll(\"form.table-row-edit-form\");\n\nfor (const f of form) {\n    wm.set(f, \"stalled\");\n}\n",[156,2514,2515,2531,2560,2564,2583,2609],{"__ignoreMap":154},[159,2516,2517,2519,2521,2523,2525,2527,2529],{"class":161,"line":162},[159,2518,1542],{"class":394},[159,2520,2292],{"class":414},[159,2522,426],{"class":418},[159,2524,470],{"class":469},[159,2526,2299],{"class":398},[159,2528,403],{"class":261},[159,2530,433],{"class":418},[159,2532,2533,2535,2538,2540,2542,2544,2547,2549,2551,2554,2556,2558],{"class":161,"line":176},[159,2534,1542],{"class":394},[159,2536,2537],{"class":414}," form",[159,2539,426],{"class":418},[159,2541,2315],{"class":446},[159,2543,450],{"class":402},[159,2545,2546],{"class":398},"querySelectorAll",[159,2548,476],{"class":261},[159,2550,479],{"class":429},[159,2552,2553],{"class":169},"form.table-row-edit-form",[159,2555,479],{"class":429},[159,2557,487],{"class":261},[159,2559,433],{"class":418},[159,2561,2562],{"class":161,"line":218},[159,2563,249],{"emptyLinePlaceholder":248},[159,2565,2566,2568,2570,2572,2575,2577,2579,2581],{"class":161,"line":245},[159,2567,1756],{"class":438},[159,2569,443],{"class":261},[159,2571,1542],{"class":394},[159,2573,2574],{"class":414}," f",[159,2576,1931],{"class":469},[159,2578,2537],{"class":446},[159,2580,463],{"class":261},[159,2582,656],{"class":402},[159,2584,2585,2588,2590,2592,2594,2597,2599,2601,2603,2605,2607],{"class":161,"line":252},[159,2586,2587],{"class":446},"    wm",[159,2589,450],{"class":402},[159,2591,2347],{"class":398},[159,2593,476],{"class":442},[159,2595,2596],{"class":446},"f",[159,2598,2358],{"class":402},[159,2600,497],{"class":429},[159,2602,2499],{"class":169},[159,2604,479],{"class":429},[159,2606,487],{"class":442},[159,2608,433],{"class":418},[159,2610,2611],{"class":161,"line":265},[159,2612,509],{"class":402},[139,2614,2615,2616,2620],{},"Then when the user is typing in an input you can capture the parent (",[1516,2617,2618],{},[1527,2619,2483],{},") and update the state",[149,2622,2624],{"className":1533,"code":2623,"language":1535,"meta":154,"style":154},"const form = document.querySelector(\"input.my-input\").parentElement;\n\nif (wm.has(form)) {\n    const state = wm.get(form);\n    switch (state) {\n        case \"editing\": {\n            wm.set(form, \"stalled\");\n            break;\n        }\n\n        case \"stalled\": {\n            wm.set(form, \"editing\");\n            break;\n        } \n    }\n}\n",[156,2625,2626,2658,2662,2685,2709,2723,2738,2763,2770,2775,2779,2793,2817,2823,2829,2833],{"__ignoreMap":154},[159,2627,2628,2630,2632,2634,2636,2638,2640,2642,2644,2647,2649,2651,2653,2656],{"class":161,"line":162},[159,2629,1542],{"class":394},[159,2631,2537],{"class":414},[159,2633,426],{"class":418},[159,2635,2315],{"class":446},[159,2637,450],{"class":402},[159,2639,2320],{"class":398},[159,2641,476],{"class":261},[159,2643,479],{"class":429},[159,2645,2646],{"class":169},"input.my-input",[159,2648,479],{"class":429},[159,2650,487],{"class":261},[159,2652,450],{"class":402},[159,2654,2655],{"class":446},"parentElement",[159,2657,433],{"class":418},[159,2659,2660],{"class":161,"line":176},[159,2661,249],{"emptyLinePlaceholder":248},[159,2663,2664,2667,2669,2671,2673,2676,2678,2681,2683],{"class":161,"line":218},[159,2665,2666],{"class":438},"if",[159,2668,443],{"class":261},[159,2670,2342],{"class":446},[159,2672,450],{"class":402},[159,2674,2675],{"class":398},"has",[159,2677,476],{"class":261},[159,2679,2680],{"class":446},"form",[159,2682,1946],{"class":261},[159,2684,656],{"class":402},[159,2686,2687,2689,2692,2694,2696,2698,2701,2703,2705,2707],{"class":161,"line":245},[159,2688,411],{"class":394},[159,2690,2691],{"class":414}," state",[159,2693,426],{"class":418},[159,2695,2292],{"class":446},[159,2697,450],{"class":402},[159,2699,2700],{"class":398},"get",[159,2702,476],{"class":442},[159,2704,2680],{"class":446},[159,2706,487],{"class":442},[159,2708,433],{"class":418},[159,2710,2711,2714,2716,2719,2721],{"class":161,"line":252},[159,2712,2713],{"class":438},"    switch",[159,2715,443],{"class":442},[159,2717,2718],{"class":446},"state",[159,2720,463],{"class":442},[159,2722,656],{"class":402},[159,2724,2725,2728,2730,2732,2734,2736],{"class":161,"line":265},[159,2726,2727],{"class":438},"        case",[159,2729,497],{"class":429},[159,2731,2490],{"class":169},[159,2733,479],{"class":429},[159,2735,419],{"class":402},[159,2737,406],{"class":402},[159,2739,2740,2743,2745,2747,2749,2751,2753,2755,2757,2759,2761],{"class":161,"line":277},[159,2741,2742],{"class":446},"            wm",[159,2744,450],{"class":402},[159,2746,2347],{"class":398},[159,2748,476],{"class":442},[159,2750,2680],{"class":446},[159,2752,2358],{"class":402},[159,2754,497],{"class":429},[159,2756,2499],{"class":169},[159,2758,479],{"class":429},[159,2760,487],{"class":442},[159,2762,433],{"class":418},[159,2764,2765,2768],{"class":161,"line":282},[159,2766,2767],{"class":438},"            break",[159,2769,433],{"class":418},[159,2771,2772],{"class":161,"line":315},[159,2773,2774],{"class":402},"        }\n",[159,2776,2777],{"class":161,"line":320},[159,2778,249],{"emptyLinePlaceholder":248},[159,2780,2781,2783,2785,2787,2789,2791],{"class":161,"line":329},[159,2782,2727],{"class":438},[159,2784,497],{"class":429},[159,2786,2499],{"class":169},[159,2788,479],{"class":429},[159,2790,419],{"class":402},[159,2792,406],{"class":402},[159,2794,2795,2797,2799,2801,2803,2805,2807,2809,2811,2813,2815],{"class":161,"line":337},[159,2796,2742],{"class":446},[159,2798,450],{"class":402},[159,2800,2347],{"class":398},[159,2802,476],{"class":442},[159,2804,2680],{"class":446},[159,2806,2358],{"class":402},[159,2808,497],{"class":429},[159,2810,2490],{"class":169},[159,2812,479],{"class":429},[159,2814,487],{"class":442},[159,2816,433],{"class":418},[159,2818,2819,2821],{"class":161,"line":357},[159,2820,2767],{"class":438},[159,2822,433],{"class":418},[159,2824,2825,2827],{"class":161,"line":686},[159,2826,1201],{"class":402},[159,2828,2361],{"class":442},[159,2830,2831],{"class":161,"line":691},[159,2832,1116],{"class":402},[159,2834,2835],{"class":161,"line":928},[159,2836,509],{"class":402},[2402,2838,2839],{},[139,2840,2841,2842,2845,2848,2851,2852,2855,2858,2861,2862,2865],{},"Then maybe after updating the state we can use ",[159,2843],{"className":2844,"style":2410},[1513],[1516,2846,2847],{},"WebSocket API",[159,2849],{"className":2850,"style":2410},[1513]," to save the data entered if state is ",[159,2853],{"className":2854,"style":2410},[1513],[1516,2856,2857],{},"\"stalled\"",[159,2859],{"className":2860,"style":2410},[1513]," or even inform other clients of the current state of the table row i.e. ",[159,2863],{"className":2864,"style":2410},[1513],[1516,2866,2867],{},"\"editing\".",[1842,2869,2871],{"id":2870},"closing-remarks",[1527,2872,2873],{},"Closing remarks",[139,2875,2876,2877],{},"The example above may resemble a real-world scenario but the truth of the matter is there is more work to it than meets the eye. That being said, you will notice that, ",[159,2878],{"className":2879,"style":1514},[1513],[1741,2881,2882,2888,2902],{},[1744,2883,2884,2885],{},"If your table is paginated then your cache will always stay fresh since it will remove the garbage collected keys. ",[159,2886],{"className":2887,"style":1514},[1513],[1744,2889,2890,2891,2894,2899],{},"The operations used by WeakMap are fast since it doesn't encourage loops hence most operations are of ",[159,2892],{"className":2893,"style":1514},[1513],[1516,2895,2896],{},[1527,2897,2898],{},"O(1).",[159,2900],{"className":2901,"style":1514},[1513],[1744,2903,2904,2905,2908,2915,2918],{},"It is extensible allowing you to create robust collections like ",[159,2906],{"className":2907,"style":1514},[1513],[1527,2909,2910],{},[2241,2911,2914],{"href":2912,"rel":2913,"target":2246},"https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FWeakMap#implementing_a_weakmap-like_class_with_a_.clear_method",[2245],"ClearableWeakMap",[159,2916],{"className":2917,"style":1514},[1513]," and you can even use them in OOP factories when managing produced objects.",[139,2920,2921,2922,2925,2932,2935],{},"All in all, I found it to be an interesting JavaScript collection. I am planning to see how I can create an ",[159,2923],{"className":2924,"style":1514},[1513],[1527,2926,2927],{},[2241,2928,2931],{"href":2929,"rel":2930,"target":2246},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInversion_of_control",[2245],"Inversion of Control (IoC)",[159,2933],{"className":2934,"style":1514},[1513]," library with it. I would love to hear the cool ways you have or would want to use WeakMap.",[139,2937,2938],{},"Thank you and Happy coding!",[1478,2940,2941],{},"html pre.shiki code .s90zX, html code.shiki .s90zX{--shiki-default:#569CD6;--shiki-dark:#C792EA;--shiki-sepia:#81A1C1}html pre.shiki code .sYz0q, html code.shiki .sYz0q{--shiki-default:#4FC1FF;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9}html pre.shiki code .skl-N, html code.shiki .skl-N{--shiki-default:#D4D4D4;--shiki-dark:#89DDFF;--shiki-sepia:#81A1C1}html pre.shiki code .s1Uiq, html code.shiki .s1Uiq{--shiki-default:#D4D4D4;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}html pre.shiki code .sRv_x, html code.shiki .sRv_x{--shiki-default:#9CDCFE;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9}html pre.shiki code .sU6aI, html code.shiki .sU6aI{--shiki-default:#D4D4D4;--shiki-dark:#EEFFFF;--shiki-sepia:#D8DEE9FF}html pre.shiki code .s7myh, html code.shiki .s7myh{--shiki-default:#CE9178;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}html pre.shiki code .sVhVX, html code.shiki .sVhVX{--shiki-default:#CE9178;--shiki-dark:#C3E88D;--shiki-sepia:#A3BE8C}html pre.shiki code .sgyjr, html code.shiki .sgyjr{--shiki-default:#9CDCFE;--shiki-dark:#F07178;--shiki-sepia:#88C0D0}html pre.shiki code .sA8ib, html code.shiki .sA8ib{--shiki-default:#9CDCFE;--shiki-dark:#89DDFF;--shiki-sepia:#ECEFF4}html pre.shiki code .s11Tq, html code.shiki .s11Tq{--shiki-default:#569CD6;--shiki-dark:#89DDFF;--shiki-sepia:#81A1C1}html pre.shiki code .sb-48, html code.shiki .sb-48{--shiki-default:#DCDCAA;--shiki-dark:#82AAFF;--shiki-sepia:#88C0D0}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 .sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html.sepia .shiki span {color: var(--shiki-sepia);background: var(--shiki-sepia-bg);font-style: var(--shiki-sepia-font-style);font-weight: var(--shiki-sepia-font-weight);text-decoration: var(--shiki-sepia-text-decoration);}html pre.shiki code .sq_UV, html code.shiki .sq_UV{--shiki-default:#C586C0;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic;--shiki-sepia:#81A1C1;--shiki-sepia-font-style:inherit}html pre.shiki code .sNvoV, html code.shiki .sNvoV{--shiki-default:#6A9955;--shiki-default-font-style:inherit;--shiki-dark:#546E7A;--shiki-dark-font-style:italic;--shiki-sepia:#616E88;--shiki-sepia-font-style:inherit}html pre.shiki code .syouj, html code.shiki .syouj{--shiki-default:#D4D4D4;--shiki-dark:#F07178;--shiki-sepia:#D8DEE9FF}html pre.shiki code .swHrb, html code.shiki .swHrb{--shiki-default:#4EC9B0;--shiki-dark:#FFCB6B;--shiki-sepia:#D8DEE9FF}",{"title":154,"searchDepth":176,"depth":176,"links":2943},[2944,2945,2946,2947],{"id":1844,"depth":176,"text":1847},{"id":2216,"depth":176,"text":2219},{"id":2448,"depth":176,"text":2451},{"id":2870,"depth":176,"text":2873},"Programming","\u002Ffotis-fotopoulos-6sAl6aQ4OWI-unsplash.jpg","Gemini said Mastering Metadata in JavaScript: Harnessing WeakMaps for Efficient, Memory-Safe Object Extensions Without Manual Cleanup or Memory Leaks. Learn how to utilize WeakMaps to attach private metadata to objects, ensuring that data is automatically garbage-collected when the object is no longer in use, thus maintaining optimal application performance and cleaner code.",{},"\u002Fblog\u002Futilizing-weakmap-to-effectively-store-metadata",null,{"title":1500,"description":2950},"blog\u002Futilizing-weakmap-to-effectively-store-metadata",[78,2957,2958],"Data Sctructures","Optimization","9WaOvagNqhwKml_88XrUQ0JQiMJThJ_8EaGQHD521uk",1774823366622]