<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: James Cardona</title>
    <description>The latest articles on DEV Community by James Cardona (@jamescardona11).</description>
    <link>https://dev.to/jamescardona11</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F620311%2F42676a79-5663-4964-8fa3-887e37a6a98c.jpg</url>
      <title>DEV Community: James Cardona</title>
      <link>https://dev.to/jamescardona11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jamescardona11"/>
    <language>en</language>
    <item>
      <title>Claves para romper la barrera del Seniority</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Thu, 05 Dec 2024 17:00:00 +0000</pubDate>
      <link>https://dev.to/jamescardona11/claves-para-romper-la-barrera-del-seniority-3k6i</link>
      <guid>https://dev.to/jamescardona11/claves-para-romper-la-barrera-del-seniority-3k6i</guid>
      <description>&lt;p&gt;Este post hace parte de la newsletter Breakthecode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbndd63pwdm58lzy23tb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdbndd63pwdm58lzy23tb.png" width="800" height="727"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Muchas personas quieren convertirse en seniors developers algún día, sin duda esto será un viaje y una experiencia nueva.&lt;/p&gt;

&lt;p&gt;Es frecuente que en ese proceso muchos fallen o se demoren más del tiempo que quieren, ¿por qué?; hay muchos factores y uno de ellos lo vimos en la edición pasada un enfoque de tiempo y energía incorrecto.&lt;/p&gt;

&lt;p&gt;Por eso debes empezar por un plan con objetivos medibles y probablemente esto suene muy obvio, un plan no garantiza el éxito, pero nos ayuda a minimizar el fracaso.&lt;/p&gt;

&lt;h2&gt;
  
  
  Estrategias para Despegar tu carrera
&lt;/h2&gt;

&lt;p&gt;Toma decisiones rápidas, se activó y proactivo en buscar ese plan y objetivos ideales para ti, esos objetivos son personales y muy específico a tus sueños o deseos, ejemplo: Ser promovido, aumentar mi salario, tener personas a cargo. &lt;/p&gt;

&lt;p&gt;La fórmula se complementa si sabes en qué nivel estás respecto a tus compañeros o personas en tu mismo rol, con eso puedes tener más claridad si tus objetivos son realistas.&lt;/p&gt;

&lt;h4&gt;
  
  
  Estableciendo metas realistas
&lt;/h4&gt;

&lt;p&gt;Es importante que establezcas metas alcanzables y realistas. Por ejemplo, podrías proponerte aprender un nuevo framework en seis meses o asumir un rol de mentor para un Junior en el próximo año. Mantén un registro de tu progreso y ajusta tu plan según sea necesario.&lt;/p&gt;

&lt;p&gt;Luego debemos crear un sistema que nos ayude a ejecutar un plan desde el punto donde estoy, un sistema es lo que conecta la intención con el objetivo, básicamente es el pegamento que mantiene mi atención en el largo plazo, este plan no es algo que puedas completar en poco tiempo, requiere energía, tiempo y disciplina.&lt;/p&gt;

&lt;p&gt;Lo que necesitamos en el sistema son los puntos de control que me ayudan a evaluar si realmente estoy avanzando, si tengo el foco puesto en lo importante para alcanzar un siguiente paso y hacer cambios si es necesario.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aprendizaje continuo:
&lt;/h3&gt;

&lt;p&gt;Los mejores ingenieros se ven a sí mismos como aprendices constantes, siempre buscando mejorar. Esa transición de junior a senior es un proceso continuo que requiere dedicación, esfuerzo y una disposición para aprender y adaptarse continuamente. Recuerda que movernos implica sentirnos incómodos con nuevas obligaciones.&lt;/p&gt;

&lt;p&gt;Al trabajar en un proyecto o empresa, seguro estemos aprendiendo mucho, pero cuando salimos de esa "burbuja", nos damos cuenta de que para mi rol en otras empresas están requiriendo cosas que no sé, el conocimiento en general en software avanza mucho a una velocidad muy alta y por eso debo ser consiente que ser desarrollador es un camino largo. &lt;/p&gt;

&lt;p&gt;No quiero que entiendas que debes abordar todo o aprender muchas cosas, en pocas palabras: Aprender y reforzar mis bases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enfóquese en construir una base técnica sólida, &lt;/li&gt;
&lt;li&gt;Desarrollar sus habilidades blandas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Toma la delantera
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1- Arquitecturas y patrones de diseño
&lt;/h4&gt;

&lt;p&gt;A medida que avanzas en tu carrera, es esencial comprender arquitecturas y patrones de diseño. Esto no solo mejora la calidad del código que produces, sino que también te permite participar en discusiones técnicas más complejas y ser visto como un líder en el equipo.&lt;/p&gt;

&lt;h4&gt;
  
  
  2-La importancia del testing
&lt;/h4&gt;

&lt;p&gt;El testing es otra área que debes dominar. Las empresas valoran a los desarrolladores que comprenden cómo implementar pruebas unitarias, pruebas de integración y pruebas de interfaz de usuario(si aplica). Esto garantiza que el código sea robusto y menos propenso a errores.&lt;/p&gt;

&lt;h4&gt;
  
  
  3- Frameworker
&lt;/h4&gt;

&lt;p&gt;Ser ingeniero significa profundizar en los fundamentos y no solo depender de frameworks, es claro que los frameworks no definen la habilidad de un developer. &lt;/p&gt;

&lt;p&gt;Yo creo que saber un framework puede ser el primer paso para conseguir un trabajo o mejorar tu puesto actual, pero en algún punto depender de un framework va a limitar las oportunidades y el crecimiento profesional.&lt;/p&gt;

&lt;p&gt;Ya lo hemos abordado mucho, pero recuerda, la programación no es solo escribir código, sino también comprender cómo y por qué funciona.  &lt;/p&gt;

&lt;h4&gt;
  
  
  4- Sigue tu pasión
&lt;/h4&gt;

&lt;p&gt;En algún punto puede que la motivación no te ayude a continuar tu camino, pero es ahí donde debes tirar del carro de la pasión, si tu pasión se alinea con tu rol, te garantizo que vas a mantener la curiosidad para solucionar, explorar o mejorar algo. Esa curiosidad en mi caso me ha ayudado mucho.&lt;/p&gt;

&lt;h4&gt;
  
  
  5- Tu empresa, el negocio, los clientes
&lt;/h4&gt;

&lt;p&gt;Aprende no solo a realizar código, aprende sobre el impacto de su trabajo en la empresa y en sus clientes, entre más entienda esto, podrás alimentar el punto anterior, y es un ciclo que se alimenta y te ayudará a crecer. &lt;/p&gt;

&lt;p&gt;Conozco casos de developers, que con profundizar en la empresa, en lo que hacen, en los puntos de dolor y empezar a aportar pudieron subir de seniority muy rápido aún con algunas habilidades técnicas por desarrollar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;La transición de desarrollador junior a senior es un viaje, no un destino. En esta serie vimos muchas cosas que seguro te van a ayudar a avanzar a senior developer.&lt;/p&gt;

&lt;p&gt;Si tienes preguntas o necesitas más consejos sobre cómo avanzar en tu carrera como desarrollador, déjalos en los comentarios. &lt;/p&gt;

&lt;p&gt;¡Ahora es tu turno! ¿Qué pasos tomarás para avanzar en tu carrera como desarrollador? Comparte tus pensamientos en los comentarios.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Break the Code: Un Nuevo Comienzo</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Tue, 12 Nov 2024 17:30:00 +0000</pubDate>
      <link>https://dev.to/jamescardona11/break-the-code-un-nuevo-comienzo-3ke0</link>
      <guid>https://dev.to/jamescardona11/break-the-code-un-nuevo-comienzo-3ke0</guid>
      <description>&lt;p&gt;Mi viaje para crear una carrera exitosa en tecnología.&lt;br&gt;
Te invito a leer y subscribirte acá: &lt;a href="https://breakthecode.substack.com/p/break-the-code-un-nuevo-comienzo" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ¿Cómo llegué hasta acá?
&lt;/h3&gt;

&lt;p&gt;Hola, a quien me esté leyendo, quisiera empezar contándote un poco de mí. Soy ingeniero de software desde hace 10 años, en su totalidad trabajando para &lt;strong&gt;startups.&lt;/strong&gt; He trabajado en diferentes industrias, áreas y stacks, pero principalmente he construido mi carrera en desarrollo móvil. Me acuerdo pasar de Eclipse a la primera beta de Android Studio 👴.&lt;/p&gt;

&lt;p&gt;Ha sido un camino más que interesante, una montaña rusa como me imagino que a todos les ha pasado, cometiendo errores, aprendiendo de otras personas, creciendo y descubriendo lo maravilloso de ser ingeniero de software.&lt;/p&gt;

&lt;p&gt;Llegó un momento de curiosidad, de construir algo más, compartir mis conocimientos con otros, así que empecé un camino de hacer muchas cosas aparte de mi trabajo normal y escribir algunos post, realmente me gusto mucho, pero lo que más me gusto, es descubrir una de mis grandes pasiones la investigación. &lt;/p&gt;

&lt;p&gt;Sin embargo, en 2024, experimenté un verdadero agotamiento. Me sentía cansado, con los ojos fatigados al trabajar y estudiar, y con poca energía para desarrollar proyectos. Decidí hacer una pausa, reducir mi carga laboral y cambiar algunos hábitos en mi vida. Tomé un tiempo para respirar, reconectarme conmigo y con mi familia, y me fui de vacaciones. Al regresar, aunque no tenía toda la energía, mi mente estaba más despejada.&lt;/p&gt;

&lt;p&gt;Después de ese periodo, durante aproximadamente tres meses, estuve tranquilo, sin hacer "mucho", digamos que solo estuve completando tareas, me dediqué a crear algunos hábitos en mi vida.&lt;br&gt;
Hasta que llego el momento de iniciar algo nuevo, luego y así nacen &lt;strong&gt;Break the Code&lt;/strong&gt; y &lt;a href="https://sinideas.substack.com/" rel="noopener noreferrer"&gt;SinIdeas&lt;/a&gt;, dos espacios que inicialmente son para mí, son una excusa para seguir desarrollando mi carrera.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixk3p8ev6k5jpe7vpfmh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fixk3p8ev6k5jpe7vpfmh.png" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  ¿Por qué escribo esta newsletter?:
&lt;/h4&gt;

&lt;p&gt;Break the Code es un viaje personal, la verdad es que esto es algo nuevo para mí. No soy un &lt;em&gt;&lt;del&gt;fancy&lt;/del&gt;&lt;/em&gt; ingeniero de una big tech, solo un tipo real con sueños y dispuesto a aportar valor.&lt;/p&gt;

&lt;p&gt;Quiero empujar los &lt;strong&gt;límites&lt;/strong&gt; de mi &lt;strong&gt;conocimiento&lt;/strong&gt;, &lt;strong&gt;disciplina&lt;/strong&gt; y mi &lt;strong&gt;impacto&lt;/strong&gt;. Hoy mi compromiso es crear algo asombroso y útil, aquí intento escribir para ti y para el futuro James 🤭.&lt;/p&gt;

&lt;p&gt;Sigo buscando muchas cosas en mi viaje como profesional, pero sin duda, sé que ya he ganado al lanzarme a hacer algo fuera de mi zona de confort, esto puede ser un poco egoísta, pero daré mi 100% para que tú también puedas ganar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gkaqpk1lap5ysutkjrk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gkaqpk1lap5ysutkjrk.png" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  El enfoque de &lt;strong&gt;Break the Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Break the Code&lt;/strong&gt; no solo se centrará en la programación, sino que también explorará herramientas, liderazgo y técnicas que pueden ayudar a los desarrolladores a mejorar su productividad, con el objetivo de crecer tu &lt;strong&gt;carrera&lt;/strong&gt;, el contenido semanal serán consejos prácticos para mejorar tus habilidades como desarrollador y crear una carrera exitosa en tecnología.&lt;/p&gt;

&lt;p&gt;También me gustaría contar con personas en este espacio a su debido momento y que podamos aprender de líderes de la industria.&lt;/p&gt;

&lt;h4&gt;
  
  
  👀 ¿Qué esperar?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lecciones aprendidas&lt;/strong&gt;, ¿qué desafíos estoy enfrentando, qué errores cometí? Estoy en la misma posición, enfrentando problemas reales.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No solo código -&lt;/strong&gt; cubriré más temas relacionados con la creación de una carrera exitosa. (🤞 - estoy en este camino)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tips:&lt;/strong&gt; Mi objetivo es compartir consejos prácticos. (al menos en la mayoría de las ediciones 🙃).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ideas&lt;/strong&gt; de side projects o proyectos que te ayuden a crecer.&lt;/li&gt;
&lt;li&gt;Consejos respaldados por experiencia personal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjn9aob3zqs63clmmtfd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbjn9aob3zqs63clmmtfd.png" width="687" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Lo siguiente 🚀
&lt;/h3&gt;

&lt;p&gt;El primer capítulo ya está programado y listo para salir, &lt;strong&gt;Mejora tu productividad: AI's esenciales para developers&lt;/strong&gt;. En ella, compartiré las herramientas de inteligencia artificial que utilizo, cómo las uso y su propósito.&lt;/p&gt;

&lt;h2&gt;
  
  
  📖 TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;La importancia de tomar un descanso, tomarse un tiempo para descansar y reconectar con uno mismo es fundamental en cualquier carrera.&lt;/li&gt;
&lt;li&gt;Disciplina para ejecutar nuestros proyectos.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break the Code&lt;/strong&gt; es un proyecto que busca descubrir y entender aspectos del desarrollo de software.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tips&lt;/strong&gt; prácticos basados en mi experiencia en la industria.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gracias por leer hasta aquí. Te invitamos a que te una en este emocionante viaje y a explorar el contenido que se lanzará cada jueves. ¡No te lo pierdas!&lt;/p&gt;

&lt;p&gt;Considera darle un me gusta, compartirlo y estar atento a futuros artículos.&lt;/p&gt;

&lt;p&gt;Subscribirte acá: &lt;a href="https://breakthecode.substack.com/p/break-the-code-un-nuevo-comienzo" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>development</category>
      <category>careerdevelopment</category>
      <category>newsletter</category>
    </item>
    <item>
      <title>Building a side project for developers - Part 2</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Fri, 24 May 2024 13:40:03 +0000</pubDate>
      <link>https://dev.to/jamescardona11/building-a-side-project-for-developers-part-2-1epm</link>
      <guid>https://dev.to/jamescardona11/building-a-side-project-for-developers-part-2-1epm</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the first part of this series, I talked about the basic things about side projects, you can read it &lt;a href="https://dev.to/jamescardona11/building-a-side-project-for-developers-part-1-4nn3"&gt;here&lt;/a&gt;. In this part, I will talk about the ideation process how to use the tools to create a plan, and how to start with the project.&lt;br&gt;
Maybe you are thinking, why do I need to create a plan? The answer is simple, the plan is the first step to start with the project, and it's a way to have a clear idea of what you want to achieve. This part is a little bit more visual and the technical solution is going to be in the next post.&lt;/p&gt;
&lt;h2&gt;
  
  
  Start with this project
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;What is the problem that I'm solving?: I'm building an AI application, that will help me and help people to improve their productivity when they are working to grow their social media.&lt;/li&gt;
&lt;li&gt;Why did I choose this idea?: Two main reasons, because I want to learn some new technologies and is something that I'm facing in my daily life.&lt;/li&gt;
&lt;li&gt;What is the goal of this project?: The idea is to have a working application for mobile and web. The main goal is for this app to use AI to create better social media content focused on LinkedIn and Twitter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With the latest questions, I can start to create a plan, the first step is to create an MVP around one single idea, and after that, I can improve it, add more features, and make it better.&lt;/p&gt;
&lt;h2&gt;
  
  
  Problem and Solution
&lt;/h2&gt;

&lt;p&gt;Focus on the Problem, Not Just the Solution&lt;/p&gt;

&lt;p&gt;Many side projects initially aim to create the next "big company" or an "automation tool for Y," leading to a fixation on a single solution. However, adopting a mindset centered around understanding the problem rather than fixating on a specific solution offers more flexibility.&lt;/p&gt;

&lt;p&gt;I'm going to write the problem description, possible features, and solution; write as much as possible, and later remove the things that are not important.&lt;/p&gt;
&lt;h3&gt;
  
  
  ⚡Problem
&lt;/h3&gt;

&lt;p&gt;Many individuals and businesses struggle to effectively grow their audience on social media platforms, hindering their ability to reach and engage with a broader audience. Despite recognizing the importance of social media presence for brand visibility and engagement, navigating the complexities of audience growth remains a significant challenge.&lt;/p&gt;

&lt;p&gt;Factors contributing to this challenge include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Limited Resources&lt;/strong&gt;: Many users lack the time, expertise, or resources to devise and implement effective audience growth strategies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Insight&lt;/strong&gt;: Users often struggle to understand their target audience, preferences, and the most effective content strategies to attract and retain followers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Management&lt;/strong&gt;: Managing multiple social media platforms, creating engaging content consistently, and scheduling posts can be overwhelming and time-consuming.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Competition&lt;/strong&gt;: The crowded social media landscape makes it difficult to stand out and attract attention amidst competition from other users and brands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Analytical Complexity&lt;/strong&gt;: Understanding the effectiveness of audience growth efforts through analytics and metrics can be daunting for many users.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  ✅ Solution
&lt;/h3&gt;

&lt;p&gt;Developing a comprehensive tool or app to address the challenge of audience growth on social media platforms requires a multifaceted approach. The solution should integrate various features and functionalities to cater to the diverse needs of users seeking to expand their reach and engagement. Key components of the solution include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Audience Insights&lt;/strong&gt;: Implement features that provide users with valuable insights into their target audience demographics, preferences, and behavior. This could include analytics dashboards, audience segmentation tools, and trend analysis capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Creation and Scheduling&lt;/strong&gt;: Offer robust content creation tools that enable users to produce high-quality, engaging content tailored to their audience. Additionally, provides scheduling features to allow users to plan and automate their social media posts for optimal timing and consistency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-Platform Integration&lt;/strong&gt;: Ensure compatibility with multiple social media platforms, allowing users to manage their presence across various channels seamlessly. This includes support for popular platforms such as Twitter, Facebook, Instagram, LinkedIn, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engagement Tools&lt;/strong&gt;: Incorporate features to facilitate user engagement, such as comment management, direct messaging, and audience interaction tracking. This encourages meaningful interactions with followers and enhances community building.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Tracking&lt;/strong&gt;: Provide comprehensive analytics and reporting functionalities to help users track the effectiveness of their audience growth efforts. Metrics such as follower growth, engagement rates, and content performance should be easily accessible and actionable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Educational Resources&lt;/strong&gt;: Offer tutorials, guides, and best practices to educate users on effective audience growth strategies and social media marketing techniques. Empowering users with knowledge and expertise enhances their ability to leverage the platform effectively.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customization and Personalization&lt;/strong&gt;: Allow users to tailor the tool to their specific needs and preferences through customizable settings, personalized recommendations, and adaptive algorithms.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Market competitors
&lt;/h2&gt;

&lt;p&gt;Search market competitors, this part is easy, you can use ProductHunt, SideProjectors, Github, and Twitter. You can find a lot of projects that are similar to your idea, and you can learn from them, what they are doing right, what they are doing wrong, and how you can improve it. &lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FVXOUwQM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FVXOUwQM.png" title="market competitors" width="780" height="991"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Why do we need to do this? The answer is simple, you need to know what is the market, what the competition is, and how you can improve your project. The idea is not to copy the project but to learn from them, and make it better.&lt;/p&gt;

&lt;h2&gt;
  
  
  MVP or MVE
&lt;/h2&gt;

&lt;p&gt;Maybe you have heard about MVP, if not, here is a simple explanation:&lt;br&gt;
Various interpretations exist for what constitutes an MVP, but generally, it refers to a product with the fewest features necessary to address the core problem.&lt;br&gt;
Confining development efforts to the MVP is crucial for two primary reasons. &lt;/p&gt;

&lt;p&gt;1) It prevents undue investment of time in building a product before confirming its market demand and user utility.&lt;/p&gt;

&lt;p&gt;2) It guards against the temptation to endlessly add features and refine the product, potentially delaying its release by months or even years.&lt;/p&gt;

&lt;p&gt;MVE (Minimum Viable Experiment) is a concept that emphasizes validating your idea with the least amount of effort. It involves creating a simple experiment to test your hypothesis and gather feedback from users. By focusing on the core assumptions of your idea and testing them quickly, you can validate your concept and make informed decisions about its viability.&lt;/p&gt;

&lt;p&gt;To solve/create this side project, I created two diagrams to explain the process and how I can solve this problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first one is using some frameworks and APIs to create the AI model and solve the problems in each step.&lt;/li&gt;
&lt;li&gt;The second one is using No-Code tools to solve the problem, here the major challenge is to create a login to use with no-code tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FS8nW96u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FS8nW96u.png" title="mvp" width="800" height="669"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Which of these two options is the best for me? I choose the first one and the second one, let me explain why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first one is the best option because I want to learn new technologies, and I want to have more control over the project.
Here the idea is simple create a first version with a single feature, that feature is something you can do directly with ChatGPT or other AI tools, but we can start collecting feedback and improve it from here. After the first launch, we can start building more features and start testing some features that are good candidates to be a premium feature.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FQJdElEi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FQJdElEi.png" title="code roadmap" width="800" height="443"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The second one is the best option because I want to have a fast MVP, and I want to have a working project as soon as possible.
The second solution is something "straightforward", using make.com as the main tool to coordinate other tools and continue with the integration of more tools, something that I want to do quickly is use the prompts that I mentioned in the first solution, and I can use the same prompts in the second solution. I can test and improve the prompts while I'm ready to start with the first solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F1d3ZcfP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F1d3ZcfP.png" title="nocode roadmap" width="800" height="493"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;With this in mind, I'm going to start with solution 2, both solutions use the same tools and I can reuse part of the things that I created with solution 2 in solution 1, and I want to start testing the idea in my social media.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be fast
&lt;/h3&gt;

&lt;p&gt;Time is of the essence, especially when considering monetizing your side project. The digital landscape is constantly evolving, and speed can be a significant advantage in gaining traction and establishing your presence. Rapid execution allows you to capitalize on emerging trends, capture market opportunities, and stay ahead of competitors.&lt;/p&gt;

&lt;p&gt;In today's fast-paced environment, being first to market often translates to a competitive edge. By swiftly bringing your side project to fruition, you can attract early adopters, generate buzz, and start generating revenue sooner. Additionally, acting swiftly enables you to iterate based on user feedback, refine your offering, and adapt to evolving market dynamics more effectively.&lt;/p&gt;

&lt;p&gt;Moreover, don't shy away from researching and analyzing potential competitors. Understanding their strategies, strengths, and weaknesses can provide valuable insights for refining your approach and positioning your side project for success. Embrace competition as a source of inspiration and motivation to continuously improve and differentiate your offering in the marketplace.&lt;/p&gt;

&lt;p&gt;In essence, speed is a vital component of success in monetizing your side project. Embrace agility, seize opportunities, and stay ahead of the curve to maximize your chances of achieving your goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI inspiration
&lt;/h3&gt;

&lt;p&gt;To this, you can do a lot of things, you can use Dribbble, Behance, Pinterest, or even some projects that you found in ProductHunt. The idea is to have a visual idea of how you want your project to look like. You can create a mood board or a simple sketch, the idea is to have a visual idea of how you want your project to look like.&lt;br&gt;
After the inspiration, you can create some low-fidelity wireframes (We are going to do this in another post), and after that, you can create high-fidelity wireframes or find someone who that create them for you.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F8PMcRX2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F8PMcRX2.png" title="ui inspiraction" width="800" height="499"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Some importantly, if you are not good with design, don't stop here your progress, the value of a project is not only driven by the design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, laying the groundwork for a successful side project involves meticulous planning and strategic decision-making. In this part of the series, we need to go deeper into the crucial steps of ideation, creating a plan, and initiating the project. Understanding the problem at hand and devising a solution that addresses its core challenges is fundamental. By focusing on the problem rather than fixating on a specific solution, we ensure flexibility and adaptability throughout the development process.&lt;/p&gt;

&lt;p&gt;Market research and competitor analysis provide invaluable insights into the existing landscape, allowing us to identify opportunities for improvement and differentiation. Establishing a Minimum Viable Product (MVP) enables us to validate our idea efficiently while avoiding unnecessary investment of time and resources.&lt;/p&gt;

&lt;p&gt;Choosing between alternative approaches, such as leveraging new technologies versus utilizing no-code tools, requires careful consideration of factors like learning objectives, time constraints, and desired outcomes. Ultimately, prioritizing speed and agility can be a significant advantage in seizing market opportunities and staying ahead of the competition.&lt;/p&gt;

&lt;p&gt;Moreover, seeking inspiration from UI designs and visualizing the project's aesthetic direction adds depth and clarity to our vision. While design is important, it's essential not to let it overshadow the project's core value proposition.&lt;/p&gt;

&lt;h3&gt;
  
  
  TIP
&lt;/h3&gt;

&lt;p&gt;Prioritize Flexibility&lt;/p&gt;

&lt;p&gt;In the early stages of product development, customer needs can change rapidly. Build flexibility into your architecture to accommodate evolving requirements as you iterate with your customers. Focus on delivering a functional product first, then refine and scale later. Don't get bogged down with elaborate processes. &lt;/p&gt;

&lt;p&gt;Prioritize building and shipping quickly, then refine and optimize as needed based on the validation of your hypothesis.&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.jointaro.com/topic/side-projects/" rel="noopener noreferrer"&gt;Side Projects - Taro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://news.ycombinator.com/item?id=14039135" rel="noopener noreferrer"&gt;Hacker News Discussion on Side Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.themuse.com/advice/6-ways-to-take-on-a-side-project-that-doesnt-take-over-your-life" rel="noopener noreferrer"&gt;6 Ways to Take on a Side Project That Doesn't Take Over Your Life&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://future.com/developers-side-projects/" rel="noopener noreferrer"&gt;Future: Developers Side Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://edward-huang.com/tech/ideas/life-lesson/2021/09/13/6-hard-truth-that-engineer-needs-to-get-over-when-working-on-side-projects/" rel="noopener noreferrer"&gt;6 Hard Truths That Engineers Need to Get Over When Working on Side Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.jotform.com/blog/build-a-startup-without-quitting-your-day-job/" rel="noopener noreferrer"&gt;Build a Startup Without Quitting Your Day Job&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.indeed.com/career-advice/career-development/how-to-create-successful-side-project" rel="noopener noreferrer"&gt;How to Create Successful Side Projects&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/how-i-built-my-side-project-and-got-31-000-users-the-first-week-d9053bae5302/" rel="noopener noreferrer"&gt;How I Built My Side Project and Got 31,000 Users the First Week&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/entrepreneur-s-handbook/mvp-is-over-you-need-to-think-about-mve-5a87bc7ca2ef" rel="noopener noreferrer"&gt;MVP is Over. You Need to Think About MVE.&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>startup</category>
      <category>sideprojects</category>
      <category>startuplife</category>
      <category>development</category>
    </item>
    <item>
      <title>Flutter Chrome Extension - Part 2</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Wed, 01 May 2024 21:05:04 +0000</pubDate>
      <link>https://dev.to/jamescardona11/flutter-chrome-extension-part-2-1kki</link>
      <guid>https://dev.to/jamescardona11/flutter-chrome-extension-part-2-1kki</guid>
      <description>&lt;p&gt;This post continues our journey to create a Chrome Extension with Flutter. In the last post, we created the base of the extension and we covered how to communicate between the extension components.&lt;/p&gt;

&lt;p&gt;We have a pending goal in order to continue the summary using ChatGPT API, we want to summarize the selected text of the current page.&lt;/p&gt;

&lt;p&gt;First part: &lt;a href="https://dev.to/jamescardona11/flutter-chrome-extension-4d2p"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal of the post
&lt;/h2&gt;

&lt;p&gt;The goal of this post is based on the following points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use dart interop to call native JS code and communicate between the extension components.&lt;/li&gt;
&lt;li&gt;Extends the knowledge on how to communicate between the extension components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://github.com/jamescardona11/flutter_chrome_extension_demo" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dart interop?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is dart interop?
&lt;/h3&gt;

&lt;p&gt;This library facilitates smooth interaction between JavaScript (JS) and Dart by providing a comprehensive JS interop solution. It's important to note that the JS types defined in this library offer static guarantees only. This means that while they provide assurances at compile time, the actual types at runtime may vary depending on the backend being used. &lt;/p&gt;

&lt;p&gt;Dart interop is included in the Flutter SDK, so we don't need to add any dependency to use it and now we can use some JS-types to convert between Dart and JS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is it useful?
&lt;/h3&gt;

&lt;p&gt;This allows us to call "JS" functions from the Dart code, note that we are not calling JS functions directly, we are calling the JS functions from the Dart code and we need to continue following the Chrome Extension rules to communicate between the components.&lt;/p&gt;

&lt;h2&gt;
  
  
  index.js
&lt;/h2&gt;

&lt;p&gt;Do you remember in the last post we created a function to get the current page URL?&lt;br&gt;
We use something like this: using the &lt;code&gt;js&lt;/code&gt; package to call the JS function from the Dart code.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'chrome'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;library&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:js/js.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'tabs.query'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Tab&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParameterQueryTabs&lt;/span&gt; &lt;span class="n"&gt;parameterQueryTabs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now we are going to use the interop to call the JS function from the Dart code.&lt;br&gt;
1) Create a new file &lt;code&gt;index.js&lt;/code&gt; in the &lt;code&gt;web&lt;/code&gt; folder.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPageUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;getPageUrl -- web/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;active&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Return from chrome.tabs.query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;2) Create a dart file, in our example we called &lt;code&gt;raw_interop.dart&lt;/code&gt;&lt;br&gt;
Here we are going to put the definition of the JS function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kn"&gt;library&lt;/span&gt; &lt;span class="n"&gt;flutter_medellin_extension&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:js_interop'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="n"&gt;JSPromise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JSString&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPageUrl&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;3) Create a second dart file, in our example, we called &lt;code&gt;js_interop.dart&lt;/code&gt;&lt;br&gt;
Here we are going to implement the call to the JS function.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;


&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'dart:js_interop'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'raw_interop.dart'&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;interop&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;JsInterop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPageUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;interop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPageUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toDart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toDart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;What is &lt;code&gt;toDart&lt;/code&gt;? This is a method that is used to convert the JS type to a Dart type.&lt;br&gt;
If you see the name of the dart function and JS function should be the same and is important to run JS code.&lt;/p&gt;

&lt;p&gt;1) Use the &lt;code&gt;JsInterop&lt;/code&gt; class to getPageUrl.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;pageUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;JsInterop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPageUrl&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Page URL: &lt;/span&gt;&lt;span class="si"&gt;$pageUrl&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Implement the selected text function
&lt;/h2&gt;

&lt;p&gt;In the index.js file, we are going to add a new function to get the selected text of the current page, but the problem is here we can't call &lt;code&gt;window&lt;/code&gt; object, we need to execute this code in the background.js.&lt;/p&gt;

&lt;p&gt;If you remember the way that we use in the latest post to communicate between components is sending messages, so we are going to use the same way to get the selected text.&lt;/p&gt;

&lt;p&gt;To send a message to the background.js we are going to use the &lt;code&gt;chrome.runtime.sendMessage&lt;/code&gt; and also we need to use the callback function to receive the return value, finally, we need to use a &lt;code&gt;Promise&lt;/code&gt; to wait before we return the code to dart side.&lt;/p&gt;

&lt;p&gt;We are going to write this in parts, first, we are going to write the JS code to get the selected text.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText -- web/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Use a promise to resolve the response from the background.js and wait for the promise to return the selected text.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Finally, the code looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText -- web/index.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Update the background.js
&lt;/h3&gt;

&lt;p&gt;Here in the background, we are going to listen to the message, and also here we need to use the &lt;code&gt;Promise&lt;/code&gt; to return the selected text.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;

    &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Two important things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can't use the &lt;code&gt;await&lt;/code&gt; in the background.js, we need to use the &lt;code&gt;Promise&lt;/code&gt; to wait for the response.&lt;/li&gt;
&lt;li&gt;We need to return &lt;code&gt;true&lt;/code&gt; to indicate that we are going to use the &lt;code&gt;sendResponse&lt;/code&gt; to send the response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is the code to get the selected text? (This code should be called inside the &lt;code&gt;Promise&lt;/code&gt;)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;currentWindow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Call the JS function from Dart
&lt;/h3&gt;

&lt;p&gt;Use the same way that we use to write and call the &lt;code&gt;getPageUrl&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;raw_interop.dart&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="n"&gt;JSPromise&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;JSString&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;js_interop.dart&lt;/strong&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;interop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toDart&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toDart&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;chrome_home_page.dart&lt;/strong&gt;&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_summarySelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Summary Selected Text'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;selectedText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;JsInterop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getSelectedText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Selected Text: &lt;/span&gt;&lt;span class="si"&gt;$selectedText&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;summaryApiClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTextSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;'Error fetching summary'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Result:&lt;br&gt;
&lt;/h3&gt;

&lt;p&gt;This is the result of the current page URL and the selected text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9hb6t391m5h2mirm2sv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9hb6t391m5h2mirm2sv.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a quick sneak peek at what other things we can do following this post and the previous post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yov7lijza0jeo7idlaf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3yov7lijza0jeo7idlaf.gif" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, we are using the communication to the contentScript.js:&lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;p&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCurrent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;windowId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;&lt;br&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;selectedText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;&lt;/p&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  What's next?&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;In this post, we covered how to use the Dart interop to call JS functions from the Dart code, and how to communicate between the extension components. I still have some pending goals to achieve using the extension. When I finish them, I will write something on my &lt;a href="https://www.linkedin.com/in/jamescardona11/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or &lt;a href="https://twitter.com/jamescardona11_" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  End words
&lt;/h2&gt;

&lt;p&gt;Creating a Chrome Extension is a challenge due to the lack of documentation and API limitations, but it's good if you want to create something quickly without needing a lot of interaction with the HTML page.&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://api.dart.dev/stable/3.3.0/dart-js_interop/dart-js_interop-library.html" rel="noopener noreferrer"&gt;https://api.dart.dev/stable/3.3.0/dart-js_interop/dart-js_interop-library.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>chromeextension</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Building a side project for developers - Part 1</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Thu, 25 Apr 2024 15:08:40 +0000</pubDate>
      <link>https://dev.to/jamescardona11/building-a-side-project-for-developers-part-1-4nn3</link>
      <guid>https://dev.to/jamescardona11/building-a-side-project-for-developers-part-1-4nn3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;What is the idea of this series?, I'll be talking about my experience, and I will share my journey of building a side project. I will share the process, the challenges, the learnings, and the outcomes. I started this journey because I wanted to learn new technologies, improve my skills, and have fun. I hope this series will inspire you to start your side project.&lt;/p&gt;

&lt;p&gt;Most importantly, even though I'm not an expert, I'm still learning. The idea is to create an AI SaaS application. I will share the process of finding the idea, the technologies that I will use, the architecture, the design, the development, the deployment, and most importantly my goals.&lt;/p&gt;

&lt;p&gt;What is a side project? A side project is a project that you work on in your free time. It can be a hobby, a way to build auto-discipline, that is the first reason that I started this journey; I want to have something to push me to learn, to explore new things, not only developer things. Something that you can have in mind, a side project is not only to get money; it's a way to improve yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  For who?
&lt;/h2&gt;

&lt;p&gt;This question can have multiple answers. But the short answer is everyone can build a Side Project, you don't need to have technical skills. In my short experience, the only skill that you need is the "desire to learn and explore new things", because you will find a lot of challenges, Do you have time? Do you have a good idea? Do you have the right skills? Do you have a bunch of projects that you started but never finished?&lt;/p&gt;

&lt;p&gt;I know this could be overwhelming, but where do you begin? What should you create? How you can balance your time? All of these questions are part of the challenge but try not to overthink, just start, just do it. So are you ready to start your side project? Let's go!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why side projects?
&lt;/h2&gt;

&lt;p&gt;There are a lot of reasons to start a side project, this is not part of your main job, but you can use this like a "takeoff ramp" to your career, here are some reasons to start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Improving Skills&lt;/li&gt;
&lt;li&gt;Portfolio Building&lt;/li&gt;
&lt;li&gt;Problem-Solving&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;li&gt;Create a passive income&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The experience that you'll get after creating or building a side project is something that can use to improve your main job or get new opportunities, the goal is to have a goal, try to achieve it, and learn with the process. &lt;br&gt;
Not all side projects are to get money, some side projects can be a way to explore things that you can't do in your daily.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to find ideas?
&lt;/h2&gt;

&lt;p&gt;The truth is I don't have a strong answer for this, but the reality is that you can find ideas everywhere. &lt;br&gt;
Here are some tips to find ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first place to start is what problems are you facing in your daily life.&lt;/li&gt;
&lt;li&gt;Follow people who are building side projects, you can find a lot of inspiration.&lt;/li&gt;
&lt;li&gt;Don't be afraid to look for inspiration in other projects, you can improve it, make it better, or more easy to use.&lt;/li&gt;
&lt;li&gt;If you are looking to change your developer career, you can start with a small project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What I'm doing right now, is solving a problem that I have and following some small project looking to learn new technologies.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to start?
&lt;/h2&gt;

&lt;p&gt;Everyone needs to create a framework that helps to start and finish the project. I'm going to share my current framework, but you can create your own, the most important thing is things that help me may not help you.&lt;/p&gt;

&lt;p&gt;1) what is the goal of building a side project, do you want to create an income or do you want to improve your skills?&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FldzThuz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FldzThuz.png" title="sideproject type"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;2) Choose the goal of your project, what do you want to achieve? &lt;br&gt;
Image your project with all the features that you want to have, and after that, you can start to create an MVP (Minimum Viable Product) which is a version of a new product that allows you to collect the maximum amount of validated learning about customers with the least effort. That MVP can be one or two main features of your project.&lt;/p&gt;

&lt;p&gt;3) You need to create a routine to work on your project, you need to be consistent start with a small goal, and increase the complexity. &lt;br&gt;
Example: start with one hour per day. You can divide that hour into small fragments of time, don't need to be one hour straight. Thing what is the best way to be productive and in balance with your life?&lt;/p&gt;

&lt;p&gt;4) Use tools to help you to collect data, track your progress, and help you to be more productive.&lt;br&gt;
Examples: Notion, Trello, Excalidraw, Miro, Figma, ClickUp, etc.&lt;/p&gt;

&lt;p&gt;5) Write a list of your skills&lt;br&gt;
We need to know what we are good at, and what we need to improve, this list can help you to find the right project for you, also we want to be faster in the execution, so if we have a good idea of what is easy for me we can start with that.&lt;/p&gt;

&lt;p&gt;6) Create a Budget&lt;br&gt;
Do you need to spend money on this project? If yes, how much? Can you use tools to help me to reduce the costs?&lt;/p&gt;

&lt;p&gt;7) Start sharing your progress, to collect feedback.&lt;/p&gt;
&lt;h3&gt;
  
  
  My personal Notion Setup
&lt;/h3&gt;

&lt;p&gt;1) Ideas Book: This space is dedicated to jotting down ideas that come to mind or are stumbled upon. The approach is simple: record the idea without overthinking it, knowing that refinement can come later. Sometimes, only the title of the problem is noted initially, with plans to revisit and enhance it later.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FNS6LG8D.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FNS6LG8D.png" title="notion book"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;2) Control tower: Here I have a board with many things related to my side project, here the ideas became projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A page to track the progress and task.&lt;/li&gt;
&lt;li&gt;A page to write some important notes from learning videos, posts, or books.&lt;/li&gt;
&lt;li&gt;Track the expenses&lt;/li&gt;
&lt;li&gt;Save other tools that help me to build the projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FK828jTs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FK828jTs.png" title="notion control-center"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;3) When starting a project, a new page is typically created with the next basic structure.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F0XlYnWk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2F0XlYnWk.png" title="notion-mvp"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚡ Problem: This section outlines the problem or pain point that your project aims to address. It provides context for why your project or product exists in the first place.&lt;/li&gt;
&lt;li&gt;✅ Solution: Here, you describe the solution you propose to solve the problem identified in the previous section. This could include features, technologies, or methodologies that you plan to implement.&lt;/li&gt;
&lt;li&gt;❓ Define the Why: This section dives deeper into the motivations behind your project. It explores the underlying reasons why addressing this particular problem is important, both to you as the creator and to potential users or stakeholders.&lt;/li&gt;
&lt;li&gt;👮 Market competitors: Here, you analyze the competitive landscape surrounding your project. This includes identifying existing solutions or competitors in the market, understanding their strengths and weaknesses, and determining how your project differentiates itself.&lt;/li&gt;
&lt;li&gt;🌟 Value-Props: This section highlights the unique value propositions of your project. It articulates the key benefits or advantages that users will gain by using your solution, helping to communicate its value effectively.&lt;/li&gt;
&lt;li&gt;💻 MVP: MVP stands for Minimum Viable Product. In this section, you outline the core features and functionalities that constitute the minimum version of your product needed to address the problem and deliver value to users. It focuses on essential elements to validate your idea and gather feedback.&lt;/li&gt;
&lt;li&gt;🚀 Launch strategy: Here, you detail your plan for launching your project or product to the market. This includes considerations such as target audience, marketing channels, timing, and any promotional activities or events.&lt;/li&gt;
&lt;li&gt;🔄 Iterate (after 🚀 Launch): This section emphasizes the importance of ongoing iteration and improvement even after the initial launch. It highlights the iterative nature of product development, where feedback from users and market insights inform continuous refinement and enhancement.&lt;/li&gt;
&lt;li&gt;📪 Associated tasks: This section lists any additional tasks or actions related to the project that need to be addressed. (Todo, In-progress, Done)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, embarking on a side project journey offers a plethora of opportunities for personal and professional growth. Whether it's to enhance skills, build a portfolio, solve problems, network, or even generate passive income, the benefits are manifold. &lt;/p&gt;

&lt;p&gt;Finding ideas may seem daunting, but they can stem from everyday challenges, inspiration from others' projects, or a desire to innovate. &lt;/p&gt;

&lt;p&gt;Establishing a structured approach, like the framework shared here, helps to navigate the complexities of side project development, from setting goals to leveraging tools for productivity and feedback. Ultimately, the journey of building a side project is as much about the process as it is about the outcome, offering valuable lessons and experiences along the way. So, if you're ready to embark on your side project adventure, remember: to just start, embrace the challenges, and enjoy the ride.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip
&lt;/h3&gt;

&lt;p&gt;To succeed in your side project, assess your available time and resources realistically. It's important to acknowledge that the project may take longer than anticipated, but the flexibility of launching it on your own schedule can be advantageous.&lt;/p&gt;

&lt;p&gt;If you can allocate time for your project, here are practical ways to track your availability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Establish a schedule: Utilize time tracking software to designate blocks of time for personal activities, work, and your side project.&lt;/li&gt;
&lt;li&gt;Rise earlier: Consider waking up an hour earlier each day to carve out extra time for your side project without compromising your primary job commitments.&lt;/li&gt;
&lt;li&gt;Prioritize your time to achieve your MVP.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sneak Peek of Part 2
&lt;/h3&gt;

&lt;p&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FEYG9jED.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FEYG9jED.png" title="notion sneak peek"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fq7fqQHS.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2Fq7fqQHS.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=1SCqveOv--c" rel="noopener noreferrer"&gt;How To Launch A SaaS From Scratch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.aimprosoft.com/blog/20-best-saas-application-ideas-for-a-profitable-product-in-2023/" rel="noopener noreferrer"&gt;20 Best SaaS Application Ideas for a Profitable Product in 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.indiehackers.com/post/how-to-get-more-ideas-for-your-saas-project-80760ffff6" rel="noopener noreferrer"&gt;How to Get More Ideas for Your SaaS Project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.indiehackers.com/post/my-step-by-step-guide-to-product-ideas-with-customers-on-auto-pilot-d808f5aafb" rel="noopener noreferrer"&gt;My Step-by-Step Guide to Product Ideas with Customers on Auto-Pilot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.indiehackers.com/post/finding-a-business-idea-that-you-ll-love-5d334da8b1" rel="noopener noreferrer"&gt;Finding a Business Idea That You'll Love&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>startup</category>
      <category>sideprojects</category>
      <category>startuplife</category>
      <category>development</category>
    </item>
    <item>
      <title>Flutter Chrome Extension - Part 1</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Sun, 24 Mar 2024 14:52:01 +0000</pubDate>
      <link>https://dev.to/jamescardona11/flutter-chrome-extension-4d2p</link>
      <guid>https://dev.to/jamescardona11/flutter-chrome-extension-4d2p</guid>
      <description>&lt;p&gt;The post will provide a comprehensive exploration of how to create a Chrome Extension Flutter; covering fundamental concepts.&lt;/p&gt;

&lt;p&gt;The true power of Flutter is its ability to create cross-platform applications allowing it to expand to the web and Chrome extension, but some important questions about creating more powerful extensions continue as a mystery for me; for that reason, this post is the beginning of the journey for me to understand how to do it.&lt;/p&gt;

&lt;p&gt;Part 2: &lt;a href="https://dev.to/jamescardona11/flutter-chrome-extension-part-2-1kki"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Goal of the post
&lt;/h2&gt;

&lt;p&gt;Before you start we need to choose the goal of the extension; in this case, we are going to create a Chrome Extension that summarizes the text of the current page using ChatGPT.&lt;/p&gt;

&lt;p&gt;In order to achieve this goal, we need to understand the following concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic setup for a Flutter Chrome Extension;&lt;/li&gt;
&lt;li&gt;How to communicate between the extension and the background script;&lt;/li&gt;
&lt;li&gt;How to inject HTML and CSS into the current page;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QGOZpeKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/IpxNxic.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QGOZpeKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/IpxNxic.gif" title="exchange SendPort" width="358" height="646"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the Extension: Basic Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  - manifest.json
&lt;/h3&gt;

&lt;p&gt;1) Create a new Flutter project;&lt;br&gt;
2) In the web folder, update the &lt;code&gt;manifest.json&lt;/code&gt; with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"flutter_chrome_extension_demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"short_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"flutter_chrome_extension_demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start_url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"display"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standalone"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"background_color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0175C2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"theme_color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#0175C2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"A new Flutter project."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"orientation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"portrait-primary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"prefer_related_applications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content_security_policy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"extension_pages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"script-src 'self' ; object-src 'self'"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default_popup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"default_icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/icons/Icon-192.png"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to know more about the &lt;code&gt;manifest.json&lt;/code&gt; file, you can check the &lt;a href="https://developer.chrome.com/docs/extensions/develop/migrate"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  - index.html
&lt;/h3&gt;

&lt;p&gt;3) Update the width and height on &lt;code&gt;index.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"height: 650px; width: 350px;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;base&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"$FLUTTER_BASE_HREF"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;flutter_chrome_extension_demo&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"manifest"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"manifest.json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="c"&gt;&amp;lt;!-- This script adds the flutter initialization JS code --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"flutter.js"&lt;/span&gt; &lt;span class="na"&gt;defer&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.dart.js"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/javascript"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Run the extension with the following command to ensure that the extension is working properly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flutter build web &lt;span class="nt"&gt;--web-renderer&lt;/span&gt; html &lt;span class="nt"&gt;--csp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Update Chrome dev tools to load the extension, and then load the extension from the &lt;code&gt;build/web&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;6) Current result:&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AzyZNUVG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/PPrGvFs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AzyZNUVG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/PPrGvFs.png" title="exchange SendPort" width="415" height="696"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How does a Chrome Extension work?
&lt;/h2&gt;

&lt;p&gt;Before we continue, let's understand how a Chrome Extension works and the different parts that make up an extension.&lt;br&gt;
A Chrome Extension consists of several parts that work together to provide the desired functionality.&lt;/p&gt;

&lt;p&gt;We are going to update the basic project to launch a popup when the counter action is clicked; in order to do that we need to update the &lt;code&gt;manifest.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"background"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"service_worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"background.js"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content_scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"matches"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;all_urls&amp;gt;"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"js"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="s2"&gt;"contentScript.js"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Excg1lDA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/W6Qf5wA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Excg1lDA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/W6Qf5wA.png" title="exchange SendPort" width="800" height="461"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Background Script:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always running, handles long-term tasks (listeners, API calls).&lt;/li&gt;
&lt;li&gt;Limited access to webpage (no direct interaction).&lt;/li&gt;
&lt;li&gt;Communicates with content script for webpage actions.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onUpdated&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;changeInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Updated to URL:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Cn97Rf2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NMXgjET.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Cn97Rf2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NMXgjET.png" title="exchange SendPort" width="800" height="59"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content Script:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Injects into webpages.&lt;/li&gt;
&lt;li&gt;Directly controls content (add, remove, modify).&lt;/li&gt;
&lt;li&gt;Runs user-facing tweaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to communicate Extension components?
&lt;/h3&gt;

&lt;p&gt;The previous image is a good representation of how the extension components communicate with each other, but you can follow the &lt;a href="https://developer.chrome.com/docs/extensions/mv3/messaging/"&gt;official documentation&lt;/a&gt; to have the full picture.&lt;/p&gt;

&lt;p&gt;Also, these two posts in StackOverflow help me to understand how to communicate between the extension components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/75789301/5179862"&gt;Post 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/12265403/passing-message-from-background-js-to-popup-js/43485784#43485784"&gt;Post 2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Steps to launch the popup
&lt;/h3&gt;

&lt;p&gt;We need to communicate using the &lt;code&gt;sendMessage&lt;/code&gt; function; in order for that work, we need to create a &lt;code&gt;listener&lt;/code&gt; to receive the message.&lt;/p&gt;

&lt;p&gt;Add permissions to the &lt;code&gt;manifest.json&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"tabs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"activeTab"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1) Create a new file &lt;code&gt;background.js&lt;/code&gt; inside the web folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;windows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCurrent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;windowId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tabId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notifications&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Create a new file &lt;code&gt;contentScript.js&lt;/code&gt; inside the web folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sendResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notifications&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;create_popup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, we need to create the &lt;code&gt;create_popup&lt;/code&gt; function to show the popup.&lt;br&gt;
You can check the &lt;code&gt;create_popup&lt;/code&gt; code in the &lt;a href="https://github.com/jamescardona11/flutter_chrome_extension_demo/blob/main/web/contentScript.js"&gt;official repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1) Finally, we need to update the &lt;code&gt;main.dart&lt;/code&gt; file to call the &lt;code&gt;sendMessage&lt;/code&gt; function when the counter is clicked.&lt;br&gt;
In order to do that, we need to add the &lt;code&gt;js&lt;/code&gt; &lt;a href="https://pub.dev/packages/js"&gt;package&lt;/a&gt;; as the description says: "Annotations to create static Dart interfaces for JavaScript APIs.&lt;/p&gt;

&lt;p&gt;Create a file called: &lt;code&gt;chrome_api.dart&lt;/code&gt; inside the &lt;code&gt;lib&lt;/code&gt; folder with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'chrome'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;library&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// library name can be whatever you want&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:js/js.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'runtime.sendMessage'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParameterSendMessage&lt;/span&gt; &lt;span class="n"&gt;parameterSendMessage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nd"&gt;@JS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nd"&gt;@anonymous&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ParameterSendMessage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;external&lt;/span&gt; &lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;ParameterSendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, update the &lt;code&gt;main.dart&lt;/code&gt; file with the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_incrementCounter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParameterSendMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;type:&lt;/span&gt; &lt;span class="s"&gt;"counter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;_counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;_counter&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result:
&lt;/h3&gt;

&lt;p&gt;With this you can see how the popup is launched when the counter is clicked; and how the components communicate with each other.&lt;/p&gt;

&lt;p&gt;This is the basic setup and how to communicate between components.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--G8nZqAUX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uPjIqJF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--G8nZqAUX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uPjIqJF.png" title="exchange SendPort" width="800" height="444"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Start summary Extension
&lt;/h2&gt;

&lt;p&gt;1) Create a ChatGPT request to summarize the text of the current page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'package:projectile/projectile.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="s"&gt;'config/env.dart'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GPTClient&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;projectile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Projectile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;client:&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;config:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BaseConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;enableLog:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPageSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;projectile&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;ProjectileRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nl"&gt;method:&lt;/span&gt; &lt;span class="n"&gt;Method&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;target:&lt;/span&gt; &lt;span class="s"&gt;'https://api.openai.com/v1/chat/completions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="n"&gt;HeadersKeys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Bearer &lt;/span&gt;&lt;span class="si"&gt;${Env.openAIKey}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="n"&gt;HeadersKeys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="s"&gt;'model'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'gpt-3.5-turbo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="s"&gt;'messages'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="s"&gt;'role'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'system'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s"&gt;'content'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'You are text summarizer tool'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="s"&gt;'role'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'user'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="s"&gt;'content'&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'Please summarize this article: &lt;/span&gt;&lt;span class="si"&gt;$url&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
          &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isFailure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;completions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;'choices'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;completions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s"&gt;'content'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Create the UI to show the summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_ChromePopupState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ChromeHomePage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;GPTClient&lt;/span&gt; &lt;span class="n"&gt;summaryApiClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GPTClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;appBar:&lt;/span&gt; &lt;span class="n"&gt;AppBar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;centerTitle:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;title:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;FlutterLogo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;size:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Chrome Demo Extension'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Choose which option to summarize'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;styleFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blueAccent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;_summaryAllPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"All page"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;width:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;ElevatedButton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;styleFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;backgroundColor:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;blueGrey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="n"&gt;_summarySelectedText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="s"&gt;"Selected text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                      &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                      &lt;span class="nl"&gt;color:&lt;/span&gt; &lt;span class="n"&gt;Colors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;white&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="s"&gt;'Summary'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="nl"&gt;style:&lt;/span&gt; &lt;span class="n"&gt;TextStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;fontSize:&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;fontWeight:&lt;/span&gt; &lt;span class="n"&gt;FontWeight&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
              &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Expanded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;SingleChildScrollView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="nl"&gt;margin:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;only&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;bottom:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                  &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;CircularProgressIndicator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="p"&gt;),&lt;/span&gt;
              &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_summarySelectedText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_summaryAllPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Summary all page'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;selectUrl&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;summaryApiClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPageSummary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="s"&gt;'Error fetching summary'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;isLoading&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;selectUrl&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;List&lt;/span&gt; &lt;span class="n"&gt;tab&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;promiseToFuture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ParameterQueryTabs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;active:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;lastFocusedWindow:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tab&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QGOZpeKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/IpxNxic.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QGOZpeKW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/IpxNxic.gif" title="exchange SendPort" width="358" height="646"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;In this post, we have covered the basic setup for a Flutter Chrome Extension, how to communicate between the extension components, and how to inject HTML and CSS into the current page.&lt;/p&gt;

&lt;p&gt;Additionally, we see how to use Flutter to call the ChatGPT API to summarize the text of the current page.&lt;/p&gt;

&lt;p&gt;Summarizing the selected text needs to be added; in the next post, we'll cover how to do that. I tried to do it in this post but needed some help with the interaction of some current JS APIs; also communicating the background/contentScript with the Extension is a challenge with Flutter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;For me creating a Chrome Extension with Flutter is a challenge; but I think that is a good way to learn more about the Flutter framework and how to use it in different scenarios.&lt;/p&gt;

&lt;p&gt;If you are thinking of creating a Chrome Extension that uses a lot of interaction with JS API; I recommend not using Flutter; in that case, it is better to use another framework.&lt;/p&gt;

&lt;p&gt;If you plan to create an extension that uses the Flutter UI; I recommend you to use Flutter; which is a good way to create a cross-platform extension.&lt;/p&gt;

&lt;p&gt;Official Github Repository: &lt;a href="https://github.com/jamescardona11/flutter_chrome_extension_demo/tree/main"&gt;Link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" alt="" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://zfinix.medium.com/building-a-chrome-extension-with-flutter-751e0674df09"&gt;https://zfinix.medium.com/building-a-chrome-extension-with-flutter-751e0674df09&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tmedanovic/XAI/tree/main"&gt;https://github.com/tmedanovic/XAI/tree/main&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@joffrey.jougon/how-to-build-a-chrome-extension-on-flutter-and-use-the-chrome-api-62798f73c16f"&gt;https://medium.com/@joffrey.jougon/how-to-build-a-chrome-extension-on-flutter-and-use-the-chrome-api-62798f73c16f&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.langchaindart.com/langchain-dart-101-developing-an-llm-powered-summarizer-browser-extension-%EF%B8%8F-8b6cab84db69"&gt;https://blog.langchaindart.com/langchain-dart-101-developing-an-llm-powered-summarizer-browser-extension-%EF%B8%8F-8b6cab84db69&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.stackademic.com/utilizing-js-library-for-flutter-web-c683c590927f"&gt;https://blog.stackademic.com/utilizing-js-library-for-flutter-web-c683c590927f&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flutter-community/building-a-chrome-extension-using-flutter-aeb100a6d6c"&gt;https://medium.com/flutter-community/building-a-chrome-extension-using-flutter-aeb100a6d6c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dhiwise.com/post/how-to-implement-flutter-js-package-in-your-flutter-apps"&gt;https://www.dhiwise.com/post/how-to-implement-flutter-js-package-in-your-flutter-apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/41273787/getting-an-arbitrary-property-from-a-javascript-object-in-dart"&gt;https://stackoverflow.com/questions/41273787/getting-an-arbitrary-property-from-a-javascript-object-in-dart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://liewjuntung.medium.com/use-javascript-in-flutter-web-a6eed3efb9a0"&gt;https://liewjuntung.medium.com/use-javascript-in-flutter-web-a6eed3efb9a0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>chromeextension</category>
    </item>
    <item>
      <title>Decoding Isolates: Basic to advanced concepts - Part3</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Sun, 24 Mar 2024 00:02:21 +0000</pubDate>
      <link>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part3-coe</link>
      <guid>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part3-coe</guid>
      <description>&lt;h2&gt;
  
  
  DEMO
&lt;/h2&gt;

&lt;p&gt;Thank you for being here in the last part of this series.&lt;br&gt;
Surely if you got this far you are like this:&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://i.giphy.com/media/wXBUASOtZCL0G1oyYi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/wXBUASOtZCL0G1oyYi/giphy.gif" title="DEMO" width="480" height="400"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I'll explain the problem and add any specific comments as needed, This use case are things that I wrote in the past to solve a problem in real apps.&lt;br&gt;
1- Image processing&lt;br&gt;
Create a solution to compress an image; move it to the internal folder of the device and show the compressed image.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSTCAXQk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GkVp5mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSTCAXQk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GkVp5mu.png" title="image processing" width="800" height="525"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a compute/Isolate.run because is a single operation&lt;/li&gt;
&lt;li&gt;Pick an image from the UI (MainIsolate) and send the image path to the Isolate&lt;/li&gt;
&lt;li&gt;Use a compress algorithm&lt;/li&gt;
&lt;li&gt;Move the isolate to the internal folder&lt;/li&gt;
&lt;li&gt;Return the new Path to the Main Isolate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From Dart 3.7 you can use background Isolates; this is a subject that I don't cover here but you can check more information here. P1.&lt;br&gt;
The operation of obtaining the internal directory of the application is an operation that requires us to use BackgroundIsolates to be able to use plugins that are not written in Dart.&lt;br&gt;
If you don't want to use BackgroundIsolates you can send the internal folder as a param.&lt;br&gt;
Trigger event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rootToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RootIsolateToken&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// get the file location&lt;/span&gt;
&lt;span class="n"&gt;newPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ImageProcessingIsolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;compressImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;FileInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;maxSize:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;&amp;lt;1MB&lt;/span&gt;
        &lt;span class="nl"&gt;fileLocation:&lt;/span&gt; &lt;span class="n"&gt;originalPath&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="nl"&gt;token:&lt;/span&gt; &lt;span class="n"&gt;rootToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isolate:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;compressImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FileInfo&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;RootIsolateToken&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;BackgroundIsolateBinaryMessenger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ensureInitialized&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;helper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CompressImageService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;fileBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_loadBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fileLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;newFileBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;helper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;executeCompression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileBytes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;internalFolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_getInternalFolder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;MoveFiles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saveInAppSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newFileBytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;internalFolder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For isolate to work it is not necessary to know what the compression and file-moving functions do, but you can explore the solutions in the repository.&lt;/p&gt;

&lt;p&gt;2- Upload images to the server.&lt;br&gt;
Upload the images to the server as a String in Base64; you can pick the images and go to another screen; the upload will be kept in the background and all screens need to listen to the updates.&lt;br&gt;
Maybe this approach is not the best way, but in one application that I wrote in the past, this was the way provided from the backend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PvDztpT1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/XcBJnDo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PvDztpT1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/XcBJnDo.png" title="image uploading" width="800" height="701"&gt;&lt;/a&gt;
&lt;/p&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a Spawn Isolate to send images to Isolates&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Starts uploading images as you select images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inform when the upload Start&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inform when the Image completes the Upload&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the Image state - Uploading/ Completed&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Show progress in the UI (How many images are left?)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a provider to listen and send messages to the isolate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The messages for the entrypoint:&lt;br&gt;
sealed class IsolateMessage {}&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateMessageData&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;IsolateMessage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateMessageClose&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;IsolateMessage&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provider; the provider is used to share the IsolateController instance between different screens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UploadImageProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;ChangeNotifier&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AttachmentInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_attachments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="n"&gt;IsolateControllerForUpload&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AttachmentInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_isolateController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;StreamSubscription&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;_subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_isolateController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;IsolateControllerForUpload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;broadcastRp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;_attachments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;addAttachments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;attachments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;attachment&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;attachments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;_attachments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attachment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;_isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attachments&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="n"&gt;notifyListeners&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfo&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;attachments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_attachments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;completedCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_attachments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;values&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;state&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;AttachmentInfoState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;totalCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_attachments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_subscription&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only difference between this IsolateControllerForUpload and the controller from the second post is the entrypoint and the In/Out models; other parts remain as in the previous implementation.&lt;/p&gt;

&lt;p&gt;Entrypoint&lt;br&gt;
When the message has a list of attachments; In this demo, we are going to process them as if they were messages with a single attachment; For that, I am going to use SwitchMap to convert the list of attachments into a list of messages with a single attachment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IsolateMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateMessage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;switchMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromIterable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;base64Converter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConvertImageToBase64&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;mockUploadImage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MockUploadImage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt; &lt;span class="nl"&gt;_:&lt;/span&gt;
      &lt;span class="c1"&gt;// Early the original list of messages; was converted into multiple messages with a single item per list.&lt;/span&gt;
      &lt;span class="c1"&gt;// This help me to achieve a better control of the state of each item.&lt;/span&gt;
      &lt;span class="c1"&gt;// You can use another approach to achieve the same result.&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfoState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploading&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;base64Converter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fileLocation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;mockUploadImage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uploadImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Uploaded'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfoState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;catchError&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;updateState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AttachmentInfoState&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageClose&lt;/span&gt; &lt;span class="nl"&gt;_:&lt;/span&gt;
      &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'closed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A possible improvement for this code is to set a limit at the same time the uploadImage method is called so as not to overwhelm the server using a queue or a similar solution.&lt;br&gt;
Now in the UI, you can use the provider to show on every screen the totalCount and the completedCount&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;symmetric&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;vertical:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;mainAxisAlignment:&lt;/span&gt; &lt;span class="n"&gt;MainAxisAlignment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Images: &lt;/span&gt;&lt;span class="si"&gt;${_provider.totalCount}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;width:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Completed &lt;/span&gt;&lt;span class="si"&gt;${_provider.completedCount}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" alt="" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;References&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.flutter.dev/perf/isolates"&gt;https://docs.flutter.dev/perf/isolates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dart.dev/language/isolates#robust-ports-example"&gt;https://dart.dev/language/isolates#robust-ports-example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dart.dev/language/concurrency"&gt;https://dart.dev/language/concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@kamal.lakhani56/isolate-flutter-74147c1df7ff"&gt;https://medium.com/@kamal.lakhani56/isolate-flutter-74147c1df7ff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flutter-community/isolates-in-flutter-a0dd7a18b7f6"&gt;https://medium.com/flutter-community/isolates-in-flutter-a0dd7a18b7f6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.codemagic.io/understanding-flutter-isolates/"&gt;https://blog.codemagic.io/understanding-flutter-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://themobilecoder.com/how-to-use-isolates-for-parallel-processing-in-flutter/"&gt;https://themobilecoder.com/how-to-use-isolates-for-parallel-processing-in-flutter/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flutter/introducing-background-isolate-channels-7a299609cad8"&gt;https://medium.com/flutter/introducing-background-isolate-channels-7a299609cad8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.flutter.dev/perf/isolates#using-platform-plugins-in-isolates"&gt;https://docs.flutter.dev/perf/isolates#using-platform-plugins-in-isolates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flutter.wtf/when-to-use-dart-isolates/"&gt;https://blog.flutter.wtf/when-to-use-dart-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://plugfox.dev/mastering-isolates/"&gt;https://plugfox.dev/mastering-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=vl_AaCgudcY"&gt;https://www.youtube.com/watch?v=vl_AaCgudcY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewzuo.com/flutter-isolates-are-good-now-81ec49e1699c"&gt;https://andrewzuo.com/flutter-isolates-are-good-now-81ec49e1699c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flutter.wtf/when-to-use-dart-isolates/"&gt;https://blog.flutter.wtf/when-to-use-dart-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://en.wikipedia.org/wiki/Actor_model"&gt;https://en.wikipedia.org/wiki/Actor_model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://www.youtube.com/watch?v=ELwEdb_pD0k"&gt;https://www.youtube.com/watch?v=ELwEdb_pD0k&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://www.youtube.com/watch?v=lPTqcecwkJg"&gt;https://www.youtube.com/watch?v=lPTqcecwkJg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@gauravswarankar/event-loop-flutter-ea025001ed1b"&gt;https://medium.com/@gauravswarankar/event-loop-flutter-ea025001ed1b&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>flutterexamples</category>
      <category>isolates</category>
    </item>
    <item>
      <title>Decoding Isolates: Basic to advanced concepts - Part2</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Sat, 23 Mar 2024 23:59:36 +0000</pubDate>
      <link>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part2-42jh</link>
      <guid>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part2-42jh</guid>
      <description>&lt;p&gt;In the previous post, we learned the basics of isolates and how to spawn them. &lt;br&gt;
In this post, we will learn how to communicate between isolates and some best practices to keep in mind when working with isolates.&lt;/p&gt;
&lt;h1&gt;
  
  
  Communicate between two isolates
&lt;/h1&gt;

&lt;p&gt;If you read the previous section, you should have a basic understanding of the Actor Model and how isolates work. Now, let's see how to communicate between two isolates using SendPort and ReceivePort.&lt;/p&gt;

&lt;p&gt;First of all, let's understand what is a SendPort and a ReceivePort.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ReceivePort&lt;/strong&gt;: It is a reference to a message queue. You can use it to receive messages from another isolate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SendPort&lt;/strong&gt;: You can use it to send messages to another isolate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A SendPort object is associated with exactly one ReceivePort. But a ReceivePort can have multiple SendPort objects associated with it.&lt;/p&gt;

&lt;p&gt;We have two ways to create a ReceivePort; RawReceivePort and ReceivePort. The difference between them is that RawReceivePort is a low-level API and ReceivePort is an API that implements the &lt;code&gt;Stream&lt;/code&gt; interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the message object is mutable; Isolate the values to avoid changing the original.&lt;/li&gt;
&lt;li&gt;If the object is immutable; Isolate the reference to the object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Steps to exchange the SendPort between isolates&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a ReceivePort before you Spawn the isolate.&lt;/li&gt;
&lt;li&gt;Pass the SendPort as an argument to the Spawned isolate. (in the entrypoint of the isolate)&lt;/li&gt;
&lt;li&gt;Create a ReceivePort in the Spawned isolate.&lt;/li&gt;
&lt;li&gt;Send the SendPort from the Spawned isolate using the SendPort to the Main Isolate.&lt;/li&gt;
&lt;li&gt;In the Main Isolate, listen to the ReceivePort or wait for the SendPort.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fnUrHaYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NYH3192.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fnUrHaYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NYH3192.png" title="exchange SendPort" width="800" height="349"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;The Same code as before to explain the steps in Spawn isolates.&lt;br&gt;
I'm going to add the entry point&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Spawn'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 1&lt;/span&gt;

    &lt;span class="c1"&gt;// --&amp;gt; Step 2&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_doSomethingForSpawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// --&amp;gt; Step 5&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We receive the SendPort from the main isolate as an argument in the entrypoint of the isolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_doSomethingForSpawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 3&lt;/span&gt;
  &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 4&lt;/span&gt;

  &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, we wait for the &lt;code&gt;SendPort&lt;/code&gt; from the SpawnedIsolate; using a completer and the first event in the Isolate listener. Later we are going to exchange this in other ways using the same concept.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY3hndWg3eWJ6ZGtuMHllbXRiejc5bXkwN210cGZod3VrOTV0Mno5MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2Je9zHYveK012EVi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY3hndWg3eWJ6ZGtuMHllbXRiejc5bXkwN210cGZod3VrOTV0Mno5MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2Je9zHYveK012EVi/giphy.gif" title="almost done" width="480" height="366"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Best practices with isolates
&lt;/h3&gt;

&lt;p&gt;The following are some best practices to keep in mind when working with isolates; we will cover these in the next examples.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error handling: Always handle errors in isolates to prevent crashes.&lt;/li&gt;
&lt;li&gt;Kill isolates: Always kill isolates when they're no longer needed.&lt;/li&gt;
&lt;li&gt;Limit communication: Avoid sending large objects between isolates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to structure?
&lt;/h2&gt;

&lt;p&gt;In the last example, we saw how to exchange the SendPort between isolates, but we can improve the structure of the code. We can explore more in-depth the concept of exchanging the SendPort between isolates.&lt;/p&gt;

&lt;p&gt;In order to follow this section; we are using the next example to explain the concept and you need to know about Streams and Futures. &lt;/p&gt;

&lt;p&gt;/// TODO&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XDXvGOdP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/lxtGGfy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XDXvGOdP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/lxtGGfy.png" title="Bidirectional communication" width="800" height="1734"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;What does this example do?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We send a Random number from the MainIsolate to the SpawnedIsolate.&lt;/li&gt;
&lt;li&gt;The SpawnedIsolate converts that number to a String and sends it back to the MainIsolate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with the entrypoint; you can change the &lt;code&gt;await for&lt;/code&gt; to &lt;code&gt;listen&lt;/code&gt; if you want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateRandomString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI shows the data and the button to send the random number to the SpawnedIsolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BidirectionalExample&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;StatefulWidget&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_BidirectionalExampleState&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;State&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BidirectionalExample&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;encodedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;lastRandomNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Scaffold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;SafeArea&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;TextButton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;onPressed:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Random number'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastRandomNumber&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Last random number: &lt;/span&gt;&lt;span class="si"&gt;$lastRandomNumber&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SizedBox&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;height:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Expanded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;ListView&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="nl"&gt;shrinkWrap:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;itemCount:&lt;/span&gt; &lt;span class="n"&gt;encodedData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="nl"&gt;itemBuilder:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Padding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nl"&gt;padding:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;EdgeInsets&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;8.0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                    &lt;span class="nl"&gt;child:&lt;/span&gt; &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encodedData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
                  &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;},&lt;/span&gt;
              &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;/// TODO&lt;br&gt;
You can find the function to generate the random number and the string in the next file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the new variables to handle the isolates and the subscription to the messages.&lt;/p&gt;

&lt;p&gt;We need the &lt;code&gt;StreamSubscription&lt;/code&gt; to cancel the subscription when the widget is disposed and  Completer to wait for the SendPort from the SpawnedIsolate.&lt;/p&gt;

&lt;p&gt;Also we keep the &lt;code&gt;Isolate&lt;/code&gt; reference to kill the Isolate when the widget is disposed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="n"&gt;StreamSubscription&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
  &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;
Create a function to run in the initState; and Spawn the isolate and create the subscription to receive messages to update the UI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;initState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;createIsolate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;createIsolate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asBroadcastStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;initSubscriptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initSubscriptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ReceivePort&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;initSendPort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;encodedData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the onPressed function to send the random number to the SpawnedIsolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendRandomNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lastRandomNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateRandomNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastRandomNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The completer indicates when the isolate is ready to receive messages; when is ready we receive the SendPort from the SpawnedIsolate and then we can send the random number.&lt;/p&gt;

&lt;p&gt;With this basic structure, we separate the logic to create the isolates and the logic that handles receiving messages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optional implementation&lt;/strong&gt;&lt;br&gt;
We want to avoid using a completer. We can use a &lt;code&gt;Stream&lt;/code&gt; to listen to the SendPort from the SpawnedIsolate.&lt;br&gt;
If you remember &lt;em&gt;ReceiverPort&lt;/em&gt; is a &lt;em&gt;Stream&lt;/em&gt; and we can use the &lt;code&gt;Stream&lt;/code&gt; methods to listen to the SendPort from the SpawnedIsolate. &lt;/p&gt;

&lt;p&gt;You need to convert the receivePort to a broadcast stream in order to get the first event that is the SendPort from the SpawnedIsolate. (Check the second line in the entrypoint)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;createIsolate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asBroadcastStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;_sendPortController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;initSubscriptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Also we can change the initSubscriptions to something like this&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;initSubscriptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;element&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;encodedData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What is missing?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;Kill isolate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are going to cover these in the next section.&lt;/p&gt;




&lt;h3&gt;
  
  
  Create a Wrapper/Controller
&lt;/h3&gt;

&lt;p&gt;The main goal is to create something to handle the isolate creation; the messages and the error handling.&lt;br&gt;
We are going to use the same example to explain the concept.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt; &lt;span class="n"&gt;_isolate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt; &lt;span class="n"&gt;_receivePort&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_broadcastRp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;_sendPort&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;
Use the same code that we have in the previous example to create the isolates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;errorsAreFatal:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asBroadcastStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;first&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;isolate:&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;receivePort:&lt;/span&gt; &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;broadcastRp:&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;sendPort:&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kd"&gt;on&lt;/span&gt; &lt;span class="kt"&gt;Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The main difference is that we are using a &lt;code&gt;try/catch&lt;/code&gt; to handle the errors and close the receivePort if something goes wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create other methods to handle the messages and close the isolates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kd"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_broadcastRp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_receivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How does the UI code change according to the new implementation?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="c1"&gt;// New variables&lt;/span&gt;
  &lt;span class="n"&gt;StreamSubscription&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Create the Isolate from the initState&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;createIsolate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;isolateController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;broadcastRp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;encodedData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OnPressed function to send the random number to the SpawnedIsolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendRandomNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lastRandomNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateRandomNumber&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

    &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastRandomNumber&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to improve the IsolateController?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In this implementation, we keep the instance of the Isolate to kill it when the widget is disposed. We can implement something to close the Isolate from inside.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can parametrize the &lt;em&gt;In&lt;/em&gt; and &lt;em&gt;Out&lt;/em&gt; data types. We can change the &lt;em&gt;In&lt;/em&gt; to use Sealed classes to handle the different types of messages that we can send to the SpawnedIsolate.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a Wrapper/Controller V2
&lt;/h3&gt;

&lt;p&gt;In this implementation you can see a different way to exchange the SendPort between isolates.&lt;br&gt;
If you want to see the full implementation using &lt;code&gt;completer&lt;/code&gt;  check this branch &lt;a href=""&gt;spawcontroller2-with-completer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This implementation uses Completer to wait for the SendPort from the SpawnedIsolate.&lt;br&gt;
What is better; use a &lt;code&gt;Stream&lt;/code&gt; or a &lt;code&gt;Completer&lt;/code&gt;; it depends on the use case my goal here is to show you the different ways to exchange the SendPort between isolates.&lt;/p&gt;

&lt;p&gt;The controller structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;_commands&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt; &lt;span class="n"&gt;_responses&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StreamController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;broadcast&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;late&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;StreamSubscription&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_subscription&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

  &lt;span class="n"&gt;Stream&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="n"&gt;broadcastRp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How is the SealedClass and the new implementation of the entrypoint?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create many classes to handle the different types of messages that we can send to the SpawnedIsolate.&lt;/span&gt;
&lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateMessage&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateMessageData&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;IsolateMessage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IsolateMessageClose&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;IsolateMessage&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;


&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="c1"&gt;// same as before&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageData&lt;/span&gt; &lt;span class="nl"&gt;_:&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageClose&lt;/span&gt; &lt;span class="nl"&gt;_:&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case to exchange the SendPort; use a completer to get from the first message in the ReceivePort; and use &lt;code&gt;RawReceivePort&lt;/code&gt; this class doesn't implement the &lt;code&gt;Stream&lt;/code&gt; interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;O&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;initPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RawReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;/// Use a callback to get the SendPort from the SpawnedIsolate&lt;/span&gt;
    &lt;span class="c1"&gt;/// The SendPort is the first message in the ReceivePort&lt;/span&gt;
    &lt;span class="n"&gt;initPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialMessage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initialMessage&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;initPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nl"&gt;errorsAreFatal:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;/// Wait to the completer&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;IsolateController&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromRawReceivePort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;initPort&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;initPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this implementation how do we close the Isolate from inside?&lt;br&gt;
Send a IsolateMessageClose close the Isolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_commands&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsolateMessageClose&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="n"&gt;_subscription&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;_responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the entryPort close the Isolate when we receive the IsolateMessageClose. Use one of these two options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolate.exit(); // This method allows to send a last message to the MainIsolate&lt;/li&gt;
&lt;li&gt;rp.close();
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_entryPoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;IsolateMessageClose&lt;/span&gt; &lt;span class="nl"&gt;_:&lt;/span&gt;
          &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;'Closed'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// or rp.close();&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the UI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call the dispose isolate method in the dispose method of the widget.&lt;/li&gt;
&lt;li&gt;The send method needs to send an IsolateMessageData to the SpawnedIsolate.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendRandomNumber&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsolateMessageData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lastRandomNumber&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@override&lt;/span&gt;
  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;isolateController&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;subscription&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Using controller v1 or v2 will depend on how you wait to develop; in the v2 to kill the Isolate; the Isolate needs to receive a message to close.&lt;/li&gt;
&lt;li&gt;Use Stream or Completer depending on what is easier for you in terms the complexity.&lt;/li&gt;
&lt;li&gt;Take in mind this is a basic structure; you can add more complexity according to your necessities.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  DEMO
&lt;/h2&gt;

&lt;p&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOXJpbzYxN25waWpkbGh0YmhoejZpOWxicGgwb3ZyMmQ3a2F4ODhhZyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/d9O5lPyufbSfZzC1pq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExOXJpbzYxN25waWpkbGh0YmhoejZpOWxicGgwb3ZyMmQ3a2F4ODhhZyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/d9O5lPyufbSfZzC1pq/giphy.gif" title="DEMO" width="500" height="281"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;The truth of Demo use cases is I'll explain the problem and add any specific comments as needed, but you can access to demo code directly from the GitHub repository.&lt;/p&gt;

&lt;p&gt;The code is inside the demo folder;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1- Image processing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSTCAXQk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GkVp5mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSTCAXQk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GkVp5mu.png" title="image processing" width="800" height="525"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a compute/Isolate.run because is a single operation&lt;/li&gt;
&lt;li&gt;Pick an image from the UI (MainIsolate) and send the image path to the Isolate&lt;/li&gt;
&lt;li&gt;Use a compress algorithm&lt;/li&gt;
&lt;li&gt;Move the isolate to the internal folder&lt;/li&gt;
&lt;li&gt;Return the new Path to the Main Isolate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1- Upload images to the server.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PvDztpT1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/XcBJnDo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PvDztpT1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/XcBJnDo.png" title="image uploading" width="800" height="701"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a Spawn Isolate to send images to Isolates&lt;/li&gt;
&lt;li&gt;Starts uploading images as you select images&lt;/li&gt;
&lt;li&gt;Inform when the Upload Start&lt;/li&gt;
&lt;li&gt;Inform when the Image completes the Upload&lt;/li&gt;
&lt;li&gt;Change the Image state - Uploading/ Completed&lt;/li&gt;
&lt;li&gt;Show progress in the UI (How many images are left?)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>flutterexamples</category>
      <category>isolates</category>
    </item>
    <item>
      <title>Decoding Isolates: Basic to advanced concepts - Part1</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Sat, 23 Mar 2024 23:56:39 +0000</pubDate>
      <link>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part1-189k</link>
      <guid>https://dev.to/jamescardona11/decoding-isolates-basic-to-advanced-concepts-part1-189k</guid>
      <description>&lt;p&gt;The post will provide a comprehensive exploration of Dart isolates, covering fundamental concepts and advanced techniques. It will delve into the basics of isolates, their role in concurrency, and how they relate to futures and streams. The discussion will extend to advanced topics, such as message passing, isolates communication, and optimizing performance also I'll show two practical demos.&lt;/p&gt;

&lt;p&gt;This post is the first part of two; in this part, we are going to see the theory in deep to understand Isolates.&lt;/p&gt;

&lt;p&gt;The second part introduces a way to create an Isolate Wrapper/Controller and shows the three demos around Isolates.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are isolates?
&lt;/h2&gt;

&lt;p&gt;An Isolate in Dart enables concurrent processing, allowing multiple tasks to run simultaneously. It operates as a "thread" with its event loop and separate memory space(it's a thread wrapper). &lt;/p&gt;

&lt;p&gt;One of the differences with threads is Isolates don't share memory and communicate with each other through messages using the &lt;strong&gt;Actor Model&lt;/strong&gt; (We'll visit this later). &lt;/p&gt;

&lt;p&gt;In Flutter, they're used to perform intensive tasks in a separate space other than the main one, preventing delays in the user interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolates enable Dart code execution separate from the main UI.&lt;/li&gt;
&lt;li&gt;They facilitate concurrent operations without blocking the UI.&lt;/li&gt;
&lt;li&gt;Isolates operate as distinct Dart VM instances enabling parallelism processing.&lt;/li&gt;
&lt;li&gt;Each isolate has its own memory space, state, and event loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why do we need them?
&lt;/h2&gt;

&lt;p&gt;Before we get into this, we first need to understand how async-await and the event handling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Loop
&lt;/h3&gt;

&lt;p&gt;Dart is single-threaded, which means it can only execute one task at a time. This is where the event loop comes in. The event loop is a queue of tasks that are executed in order. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Imagine you're in a busy coffee-shop where a barista handles orders efficiently. The barista represents Flutter's event loop, constantly processing orders (events) from customers (user interactions). Just like the barista ensures everyone gets served promptly, Flutter's event loop keeps the app responsive to user actions and updates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Async-Await
&lt;/h3&gt;

&lt;p&gt;Async doesn't mean parallel, it means non-blocking. When you call an async function, it returns a Future immediately. The function continues to execute, and when it's done, it completes the Future. This is the basis of the event loop, which is a queue of tasks that are executed in order. &lt;/p&gt;

&lt;p&gt;Suppose you have an I/O operation to read a JSON file, the event loop will work like this:&lt;/p&gt;

&lt;p&gt;1- We receive the request to read the file.&lt;br&gt;
2- The event loop will add the task to the queue.&lt;br&gt;
3- The event loop will continue to process other tasks.&lt;br&gt;
4- When the file is read, the event loop will execute the callback.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8tJPUOY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6CRRBd4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8tJPUOY3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6CRRBd4.png" title="async event loop" width="730" height="654"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;More information about this can be found in the &lt;a href="https://www.youtube.com/watch?v=OTS-ap9_aXc"&gt;Dart Futures - Flutter in Focus&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event handling
&lt;/h3&gt;

&lt;p&gt;Isolate encapsulates a wrapper around thread; each isolate ha with its event loop managing queued events. Events, representing user interactions, are processed by the event loop in a FIFO manner. This ensures the timely execution of app actions.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pM_NLIaa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/tmJCaD9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pM_NLIaa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/tmJCaD9.png" title="event handling" width="800" height="350"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;For a moment let's imagine that we have to do an I/O operation like reading a JSON; that this file is very large and the task takes a long time to complete. Now the event queue and the event loop look similar to the image below.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jVg9ikxi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/81AjG4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jVg9ikxi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/81AjG4r.png" title="event handling jank" width="357" height="585"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Since the main isolate struggles to promptly process events, our animations or UI may freeze, frustrating users and causing significant drop-offs. Here's where creating a new isolate or a worker isolate becomes crucial.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaXdud2QzYnNoNnRxMjBvcnEyZzlhd3FqdXloZjAzMGt5eG1rYWlpMyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o6gDSdED1B5wjC2Gc/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExaXdud2QzYnNoNnRxMjBvcnEyZzlhd3FqdXloZjAzMGt5eG1rYWlpMyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3o6gDSdED1B5wjC2Gc/giphy.gif" title="gif overload information" width="480" height="378"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let’s get back to Isolates.; why do we need them?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt;: Execute Dart code simultaneously, without affecting the main thread.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation&lt;/strong&gt;: Each isolate has its memory, avoiding data issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallelism&lt;/strong&gt;: Run code on multiple CPU cores for better performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication&lt;/strong&gt;: Isolates exchange messages to share information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background Processing&lt;/strong&gt;: Run time-consuming tasks in the background without UI impact.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy task&lt;/strong&gt;: Like image processing or data fetching.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to implement Isolates?
&lt;/h2&gt;

&lt;p&gt;Basically, there are two ways to create an isolate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compute Isolate (This use Isolate.run)&lt;/li&gt;
&lt;li&gt;Spawn Isolate (This use Isolate.spawn)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we mentioned before, Isolates unlike threads, don't share memory, and communicate with each other through messages using the &lt;strong&gt;Actor Model&lt;/strong&gt;. This means that you can't share data between isolates, you need to send messages to communicate between them.&lt;/p&gt;

&lt;p&gt;The entry point of an isolate is a function and must be a top-level or static function. Depending on the method you use to create an isolate, you can pass arguments to the function.&lt;/p&gt;

&lt;p&gt;Here is the &lt;a href="https://github.com/jamescardona11/isolates"&gt;link&lt;/a&gt; to the code if you want to follow along.&lt;/p&gt;

&lt;p&gt;Image you need to calculate a progressive sum of a number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Doing something'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'finished &lt;/span&gt;&lt;span class="si"&gt;${sum}&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'InitializeAppData Completed in &lt;/span&gt;&lt;span class="si"&gt;${timer.elapsedMilliseconds}&lt;/span&gt;&lt;span class="s"&gt; ms'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;timer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you try to execute this function without using an isolate, you will notice that the UI will freeze for a few seconds. This is because the main isolate is busy calculating the sum, and it can't process any other events.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compute Isolate
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;compute&lt;/code&gt; or &lt;code&gt;Isolate.run&lt;/code&gt; function creates an isolate and runs the specified function in it. This is useful for short-lived tasks that don't require continuous communication between isolates. &lt;/p&gt;

&lt;p&gt;You can use &lt;code&gt;compute&lt;/code&gt; or &lt;code&gt;Isolate.run&lt;/code&gt; to execute the function in a separate isolate. Both methods return a Future that completes with the result of the function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;computeIsolate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Compute'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;compute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;runIsolate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Run'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Spawn Isolate
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;spawn&lt;/code&gt; function creates an isolate and runs the specified function in it. This is useful for long-lived tasks that require continuous communication between isolates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Spawn'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_doSomethingForSpawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next image, you can see the difference between the do the execution in main isolate and use an isolate.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EMwM44Xv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/vwvE2E8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EMwM44Xv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/vwvE2E8.gif" title="Result" width="600" height="1302"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;// TODO&lt;br&gt;
The code of this specific example is here &lt;a href=""&gt;link&lt;/a&gt;; inside the learning 1 folder.&lt;/p&gt;

&lt;p&gt;I'll return later to explain the steps of the spawn function also we need to cover what is a &lt;code&gt;SendPort&lt;/code&gt; and a &lt;code&gt;ReceivePort&lt;/code&gt;, and how to use them to communicate between isolates; before that, I want to give you a brief explanation of the Actor Model.&lt;/p&gt;
&lt;h2&gt;
  
  
  Actor Model
&lt;/h2&gt;

&lt;p&gt;If you want to understand in more detail what the paradigm is that drives how isolates work?, this section is a summary of it; As a personal appreciation, this helped me understand how to create good architecture around the Isolates; but you are free to skip to the next session.&lt;/p&gt;

&lt;p&gt;Concurrency models&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Processes&lt;/li&gt;
&lt;li&gt;Threads&lt;/li&gt;
&lt;li&gt;Futures&lt;/li&gt;
&lt;li&gt;Coroutines&lt;/li&gt;
&lt;li&gt;Actor&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What is the Actor Model?
&lt;/h3&gt;

&lt;p&gt;The actor model is a concurrent programming that is based on the concept of actors. An actor is an entity that encapsulates state and behavior, communicates with other actors by sending and receiving messages, and processes messages sequentially.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key concepts:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Actors are persistent.&lt;/li&gt;
&lt;li&gt;Encapsulate internal state (Private).&lt;/li&gt;
&lt;li&gt;Actors are asynchronous.&lt;/li&gt;
&lt;li&gt;Communication through messages.&lt;/li&gt;
&lt;li&gt;Independence between actors.&lt;/li&gt;
&lt;li&gt;Supervision.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What can actors do?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create new actors.&lt;/li&gt;
&lt;li&gt;Send messages to other actors.&lt;/li&gt;
&lt;li&gt;Receive messages and in-responses.&lt;/li&gt;
&lt;li&gt;Process exactly one message at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;“Do not communicate by sharing memory; instead, share memory by communicating" | Effective Go&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Properties of communication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NO channels or intermediaries.&lt;/li&gt;
&lt;li&gt;“best effort” delivery.&lt;/li&gt;
&lt;li&gt;Messages can take an arbitrarily long time to deliver.&lt;/li&gt;
&lt;li&gt;No message ordering guarantees.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Address&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each actor has an address.&lt;/li&gt;
&lt;li&gt;Actors can communicate with other actors using their addresses (Use SendPort to send messages).&lt;/li&gt;
&lt;li&gt;The actor receives addresses from other actors in messages (Listen ReceivePort).&lt;/li&gt;
&lt;li&gt;One actor can have more than one address.&lt;/li&gt;
&lt;li&gt;Address != identify; this means two actors with the same identity can have different addresses.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Supervision&lt;/strong&gt;&lt;br&gt;
The running state of an actor is monitored and managed by another&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constantly monitors the running state of the actor (is alive, restart)&lt;/li&gt;
&lt;li&gt;Can perform actions based on the state of the actor (eg unhandled error)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5qiNW86u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GHsB9Kd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5qiNW86u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/GHsB9Kd.png" title="supervisor" width="667" height="385"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Isolates similarities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ReceiverPort is a similar concept to Actor Mailbox.&lt;/li&gt;
&lt;li&gt;The Mailbox is a message queue.&lt;/li&gt;
&lt;li&gt;SendPort is a similar address concept in the actor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the basic concept of the Actor Model, and it's the base of how isolates work. With this in mind, we can understand how to use &lt;code&gt;SendPort&lt;/code&gt; and &lt;code&gt;ReceivePort&lt;/code&gt; to communicate between isolates. &lt;/p&gt;

&lt;p&gt;Here is a summary of the difference between &lt;strong&gt;Isolates&lt;/strong&gt; and &lt;strong&gt;Threads&lt;/strong&gt; that are provided by the Actor Model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolation of memory: Isolates don’t share memory and the data is passed through messages.&lt;/li&gt;
&lt;li&gt;Lightweight: You can create thousands of isolates.&lt;/li&gt;
&lt;li&gt;Safe concurrency: Isolates provide a safe way to perform concurrent operations, minimizing the risk of common concurrency issues like deadlocks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Communicate between two isolates
&lt;/h2&gt;

&lt;p&gt;If you read the previous section, you should have a basic understanding of the Actor Model and how isolates work. Now, let's see how to communicate between two isolates using &lt;code&gt;SendPort&lt;/code&gt; and &lt;code&gt;ReceivePort&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First of all, let's understand what is a &lt;code&gt;SendPort&lt;/code&gt; and a &lt;code&gt;ReceivePort&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReceivePort&lt;/strong&gt;: It is a reference to a message queue. You can use it to &lt;strong&gt;receive&lt;/strong&gt; messages from another isolate.&lt;br&gt;
&lt;strong&gt;SendPort&lt;/strong&gt;: You can use it to &lt;strong&gt;send&lt;/strong&gt; messages to another isolate.&lt;/p&gt;

&lt;p&gt;A SendPort object is associated with exactly one ReceivePort. But a ReceivePort can have multiple SendPort objects associated with it.&lt;/p&gt;

&lt;p&gt;We have two ways to create a ReceivePort; RawReceivePort and ReceivePort. The difference between them is that RawReceivePort is a low-level API and ReceivePort is a high-level API that this implements the &lt;code&gt;Stream&lt;/code&gt; interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the messages object is mutable; Isolates the values to avoid change the original.&lt;/li&gt;
&lt;li&gt;If the object is immutable; Isolates the reference to the object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Steps to exchange the SendPort between isolates&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a ReceivePort before you Spawn the isolate.&lt;/li&gt;
&lt;li&gt;Pass the SendPort as argument to the Spawned isolate. (in the entrypoint of the isolate)&lt;/li&gt;
&lt;li&gt;Create a ReceivePort in the Spawned isolate.&lt;/li&gt;
&lt;li&gt;Send the SendPort from the Spawned isolate using the SendPort to the Main Isolate.&lt;/li&gt;
&lt;li&gt;In the Main Isolate, listen to the ReceivePort or wait for the SendPort.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fnUrHaYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NYH3192.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fnUrHaYF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/NYH3192.png" title="exchange SendPort" width="800" height="349"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Same code as before to explain the steps in Spawn isolates.&lt;br&gt;
I'm going to add the entry point&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Spawn'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 1&lt;/span&gt;

    &lt;span class="c1"&gt;// --&amp;gt; Step 2&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_doSomethingForSpawn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Completer&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// --&amp;gt; Step 5&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="n"&gt;SendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;kill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;send2Isolate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;completer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;future&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;send2Isolate&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We receive the SendPort from the main isolate as argument in the entrypoint of the isolate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;_doSomethingForSpawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SendPort&lt;/span&gt; &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;rcvPort&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReceivePort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 3&lt;/span&gt;
  &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sendPort&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// --&amp;gt; Step 4&lt;/span&gt;

  &lt;span class="n"&gt;rcvPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;sendPort&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case we wait for the &lt;code&gt;SendPort&lt;/code&gt; from the SpawnedIsolate; using a completer and the first event in the Isolate listener. Later we are going to exchange this in other ways using the same concept.&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY3hndWg3eWJ6ZGtuMHllbXRiejc5bXkwN210cGZod3VrOTV0Mno5MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2Je9zHYveK012EVi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/v1.Y2lkPTc5MGI3NjExY3hndWg3eWJ6ZGtuMHllbXRiejc5bXkwN210cGZod3VrOTV0Mno5MyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/l2Je9zHYveK012EVi/giphy.gif" title="almost done" width="480" height="366"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Best practices with isolates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Error handling: Always handle errors in isolates to prevent crashes.&lt;/li&gt;
&lt;li&gt;Kill isolates: Always kill isolates when they're no longer needed.&lt;/li&gt;
&lt;li&gt;Limit communication: Avoid sending large objects between isolates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See you in the next part where we will apply concepts from the Actor model to create a Wrapper/Controller for our Isolates&lt;/p&gt;

&lt;p&gt;Thank you for reading this far. Consider giving it a like, sharing it, and staying tuned for future articles. Feel free to contact me via &lt;a href="https://www.linkedin.com/in/jamescardona11/"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" alt="" width="480" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.flutter.dev/perf/isolates"&gt;https://docs.flutter.dev/perf/isolates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dart.dev/language/isolates#robust-ports-example"&gt;https://dart.dev/language/isolates#robust-ports-example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dart.dev/language/concurrency"&gt;https://dart.dev/language/concurrency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@kamal.lakhani56/isolate-flutter-74147c1df7ff"&gt;https://medium.com/@kamal.lakhani56/isolate-flutter-74147c1df7ff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flutter-community/isolates-in-flutter-a0dd7a18b7f6%C2%A0"&gt;https://medium.com/flutter-community/isolates-in-flutter-a0dd7a18b7f6 &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.codemagic.io/understanding-flutter-isolates/"&gt;https://blog.codemagic.io/understanding-flutter-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://themobilecoder.com/how-to-use-isolates-for-parallel-processing-in-flutter/"&gt;https://themobilecoder.com/how-to-use-isolates-for-parallel-processing-in-flutter/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/flutter/introducing-background-isolate-channels-7a299609cad8"&gt;https://medium.com/flutter/introducing-background-isolate-channels-7a299609cad8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.flutter.dev/perf/isolates#using-platform-plugins-in-isolates"&gt;https://docs.flutter.dev/perf/isolates#using-platform-plugins-in-isolates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flutter.wtf/when-to-use-dart-isolates/"&gt;https://blog.flutter.wtf/when-to-use-dart-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://plugfox.dev/mastering-isolates/"&gt;https://plugfox.dev/mastering-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=vl_AaCgudcY"&gt;https://www.youtube.com/watch?v=vl_AaCgudcY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://andrewzuo.com/flutter-isolates-are-good-now-81ec49e1699c"&gt;https://andrewzuo.com/flutter-isolates-are-good-now-81ec49e1699c&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.flutter.wtf/when-to-use-dart-isolates/"&gt;https://blog.flutter.wtf/when-to-use-dart-isolates/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://en.wikipedia.org/wiki/Actor_model"&gt;https://en.wikipedia.org/wiki/Actor_model&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://www.youtube.com/watch?v=ELwEdb_pD0k"&gt;https://www.youtube.com/watch?v=ELwEdb_pD0k&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Actor Model: &lt;a href="https://www.youtube.com/watch?v=lPTqcecwkJg"&gt;https://www.youtube.com/watch?v=lPTqcecwkJg&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@gauravswarankar/event-loop-flutter-ea025001ed1b"&gt;https://medium.com/@gauravswarankar/event-loop-flutter-ea025001ed1b&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>flutterexamples</category>
    </item>
    <item>
      <title>Git para todos. Parte 4 - Deshacer errores</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Wed, 25 May 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/jamescardona11/git-para-todos-parte-4-deshacer-errores-5h1c</link>
      <guid>https://dev.to/jamescardona11/git-para-todos-parte-4-deshacer-errores-5h1c</guid>
      <description>&lt;p&gt;Los errores pueden pasar, el desarrollo de software es un proceso creativo y que involucra personas, las personas cometemos errores.&lt;br&gt;
Para eso es git, es nuestro helper, nuestra muralla para combatir errores.&lt;/p&gt;



&lt;p&gt;La recomendación para sacar el máximo provecho a este tutorial es preparar un ambiente para ver en acción como operan las diferentes condiciones.&lt;br&gt;
Con todo lo que has aprendido hasta acá va a ser muy fácil para ti preparar ese ambiente de trabajo. Puedes usar este cómo &lt;strong&gt;base&lt;/strong&gt; para iniciar &lt;a href="https://github.com/jamescardona11/git-exercism"&gt;github&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1 Descartar todos los cambios en un archivo (uncommitted)
&lt;/h3&gt;

&lt;p&gt;Pre: Edita un archivo que estemos traqueando y que no hayamos confirmado los cambios&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git restore &amp;lt;file-name&amp;gt;&lt;/code&gt; o&lt;br&gt;
-&amp;gt; &lt;code&gt;git checkout &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2 Restaurar un archivo eliminado (uncommitted)
&lt;/h3&gt;

&lt;p&gt;Pre: Elimina un archivo que estemos traqueando y que no hayamos confirmado el borrado&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git restore &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3 Descartar algunas líneas de un archivo (uncommitted)
&lt;/h3&gt;

&lt;p&gt;Pre: Edita un archivo que estemos traqueando diferentes líneas de código y que no hayamos confirmado los cambios&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git restore -p &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  4 Descartar todos los cambios en local (uncommitted)
&lt;/h3&gt;

&lt;p&gt;Pre: Edita multiples archivo que estemos traqueando diferentes líneas de código y que no hayamos confirmado los cambios&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git restore .&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  5 Arreglar el último commit
&lt;/h3&gt;

&lt;p&gt;Pre: Has un commit y copia mal el mensaje o deja algunos archivos sin completar&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git commit --amend -m &amp;lt;new-message&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Si quieres agregar algo que olvidaste&lt;br&gt;
-&amp;gt; &lt;code&gt;git add .&lt;/code&gt;&lt;br&gt;
-&amp;gt; &lt;code&gt;git commit --amend -m &amp;lt;new-message&amp;gt;&lt;/code&gt; o &lt;code&gt;git commit --amend --no-edit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;amend&lt;/strong&gt; es un comando que reescribe el historial y si lo reescribimos debemos tener cuidado con los cambios en remoto&lt;/p&gt;
&lt;h3&gt;
  
  
  6 Revertir un commit en la mitad del proceso
&lt;/h3&gt;

&lt;p&gt;Pre: Busca un estado previo(hash) de un commit para restaurar a ese estado&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git revert &amp;lt;hash&amp;gt;&lt;/code&gt;&lt;br&gt;
Cuando se hace esto git va a crear un nuevo commit con el estado del revert&lt;/p&gt;
&lt;h3&gt;
  
  
  7 Resetear a una versión anterior
&lt;/h3&gt;

&lt;p&gt;Pre: Busca un estado previo(hash) de un branch para resetear a ese estado&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git reset --hard &amp;lt;#hash&amp;gt;&lt;/code&gt;&lt;br&gt;
Cuidado que el --hard va a eliminar los commits después del hash destino&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git reset --mixed &amp;lt;#hash&amp;gt;&lt;/code&gt;&lt;br&gt;
Mantienen los cambios descartados como cambios locales, para que puedas trabajar con ellos, modificarlos, etc.&lt;/p&gt;
&lt;h3&gt;
  
  
  8 Resetear un archivo a versión anterior
&lt;/h3&gt;

&lt;p&gt;Pre: Busca un estado previo(hash) de un branch para resetear a ese estado&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git restore --source &amp;lt;#hash&amp;gt; &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  9 Recuperar commits borrados
&lt;/h3&gt;

&lt;p&gt;Pre: Después de realizar el punto #8 puedes buscar el hash desde donde partiste para hacer el reset&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git reflog&lt;/code&gt; search the hash o HEAD# antes del reset&lt;br&gt;
-&amp;gt; &lt;code&gt;git branch &amp;lt;branch-name&amp;gt; &amp;lt;#hash&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  10 Recuperar una rama borrada
&lt;/h3&gt;

&lt;p&gt;Pre: Buscar el hash desde donde partiste para borrar la rama&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git reflog&lt;/code&gt; search the hash o HEAD# de la rama&lt;br&gt;
-&amp;gt; &lt;code&gt;git branch &amp;lt;branch-name&amp;gt; &amp;lt;#hash&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  11 Mover un commit a una nueva rama
&lt;/h3&gt;

&lt;p&gt;Pre: Crea un commit en una branch&lt;/p&gt;

&lt;p&gt;-&amp;gt; &lt;code&gt;git branch &amp;lt;branch-name&amp;gt;&lt;/code&gt;&lt;br&gt;
-&amp;gt; &lt;code&gt;git reset HEAD~1 --hard&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  12 Mover un commit a una rama diferente
&lt;/h3&gt;

&lt;p&gt;Pre: Crea dos branch con al menos un commit en cada una, mueve uno de los commit a la otra rama&lt;/p&gt;

&lt;p&gt;-&amp;gt; movernos a la rama destino &lt;code&gt;switch&lt;/code&gt; o &lt;code&gt;checkout&lt;/code&gt;&lt;br&gt;
-&amp;gt; &lt;code&gt;git cherry-pick &amp;lt;hash&amp;gt;&lt;/code&gt;&lt;br&gt;
-&amp;gt; movernos a la rama origen de donde movimos el commit&lt;br&gt;
-&amp;gt; &lt;code&gt;git reset HEAD~1 --hard&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Conclusiones
&lt;/h3&gt;

&lt;p&gt;Si llegaste hasta acá gracias por todo.&lt;br&gt;
Puedes consultar más casos &lt;a href="https://firstaidgit.io/#/"&gt;acá&lt;/a&gt;, adicional te invito a dejarme nuevos casos y si quieres que hagamos algunos más.&lt;br&gt;
Puedes buscarme en &lt;a href="https://www.linkedin.com/posts/jamescardona11_my-tech-blog-jamescardona11-activity-6932922428423634944-RDfk?utm_source=linkedin_share&amp;amp;utm_medium=member_desktop_web"&gt;Linkedin&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Referencias
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.git-tower.com/learn/git/ebook"&gt;Git-tower&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/"&gt;Git-Oficial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lab.github.com/"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/book/es/v2"&gt;Git book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://books.google.com.co/books/about/Version_Control_with_Git.html?id=qIucp61eqAwC&amp;amp;redir_esc=y"&gt;Version control Git - Book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=lX9hsdsAeTk"&gt;Video&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;

&lt;p&gt;Gracias por llegar hasta acá, considera dar un like, compartir y nos vemos en un próximo artículo.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--99hjEHHr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://i.imgur.com/q7fqQHS.gif" width="480" height="320"&gt;&lt;/a&gt;
&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Git para todos. Parte 3 - Uso avanzado</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Sat, 21 May 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/jamescardona11/git-para-todos-parte-3-uso-avanzado-3fgo</link>
      <guid>https://dev.to/jamescardona11/git-para-todos-parte-3-uso-avanzado-3fgo</guid>
      <description>&lt;p&gt;Si llegaste hasta acá, estoy seguro que ya tienes dominado gran parte de lo que se requiere para ser un pro en git.&lt;br&gt;
En este tutorial y el próximo vamos a ver algunas situaciones particulares y como las podemos gestionar con git.&lt;br&gt;
Ese es el objetivo poder entrar a entender y resolver situaciones difíciles.&lt;/p&gt;


&lt;h3&gt;
  
  
  Volvamos a lo básico - Un buen commit
&lt;/h3&gt;

&lt;p&gt;¿Cómo definimos un buen commit? ¿Por qué me debo preocupar por esto ?&lt;br&gt;
La verdad la razón base por volver a tratar este tema acá es que cuando estoy desarrollando debo pensar como solucionar problemas que pueda tener el "yo futuro"&lt;/p&gt;

&lt;p&gt;Una de la forma de hacerlo es creando commits adecuados que me permitan solucionar problemas futuros.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compacto:&lt;/strong&gt; Los cambios deben ser específicos o relacionados.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Descriptivo:&lt;/strong&gt; Debe ser legible la solución, los pendientes y que hiciste&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pensar en el futuro:&lt;/strong&gt; Un buen commit va a ayudar hacer un tracking de posibles errores en el futuro&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Propuesta para los commits:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;type&amp;gt;: &amp;lt;description&amp;gt;
[optional body]

[] List of changes

[optional scope]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ejemplo:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix: fix the animation for drawer

[X] Add new flag to control the state when is open
[X] Test on android and iOS
[ ] is pending interact with ....

TOK-1766 Jira
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto fue tomado de acá: &lt;a href="https://udacity.github.io/git-styleguide/"&gt;https://udacity.github.io/git-styleguide/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Stash
&lt;/h3&gt;

&lt;p&gt;¿Qué pasa si tengo trabajo iniciado y debía hacer algo antes de iniciar?&lt;br&gt;
Tengo que ayudar a alguien y necesito "descartar" mi trabajo temporal. En cualquier caso similar no quiero perder mi avance y tampoco quiero hacer un commit.&lt;/p&gt;

&lt;p&gt;Git nos da la posibilidad de usar un "sub-espacio" temporal, esto es lo que se conoce como &lt;strong&gt;stash&lt;/strong&gt;, esté espacio temporal nos permite guardar cambios sin llevarlos al historial de commits.&lt;/p&gt;

&lt;h4&gt;
  
  
  Comandos básicos
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git stash&lt;/code&gt;: Para guardar cambios sin commit&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash list&lt;/code&gt;: Para listar los que tenemos en el stash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash show&lt;/code&gt;: Muestra el último stash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash show stash@{1}&lt;/code&gt;: Muestra un stash específico&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash pop&lt;/code&gt;: Aplica los cambios a nuestro workspace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash drop&lt;/code&gt;: Descarta los cambios&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash clear&lt;/code&gt;: Descarta todos los cambios&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash branch &amp;lt;branch-name&amp;gt;&lt;/code&gt;: Crear una rama nueva desde el último stash&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git stash branch &amp;lt;branch_name&amp;gt; stash@{#}&lt;/code&gt;: Crear una rama nueva desde un stash específico&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cuando usamos el comando &lt;code&gt;git stash list&lt;/code&gt; sale algo parecido a esto:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---DV3nJyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/7jufv66.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---DV3nJyN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/7jufv66.png" alt="stash-list" width="348" height="58"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Entendamos está información:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stash@{0}– esto es solo una referencia oculta. Se refiere al stash particular. De forma predeterminada, Stash@{0}siempre es el último stash.&lt;/li&gt;
&lt;li&gt;WIP On rama– rama es solo un nombre de branch como cualquier otra branch y WIP significa &lt;em&gt;Work In Progress&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;8177255 &amp;lt;...&amp;gt;&lt;/code&gt; es el hash de confirmación y un breve encabezado&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reset
&lt;/h3&gt;

&lt;p&gt;Esté es un comando muy peligroso porque puede dañar nuestro trabajo si se utiliza mal, pero es muy útil para muchas cosas.&lt;br&gt;
El &lt;strong&gt;reset&lt;/strong&gt; es básicamente volver a un estado anterior, una branch, un archivo, un commit.&lt;/p&gt;

&lt;p&gt;Generalmente, es usado para devolver el estado de una branch que se dañó luego de un merge o algún cambio no deseado. Por el momento vamos a ver este comportamiento y ampliaremos más su uso en el próximo tutorial.&lt;/p&gt;

&lt;p&gt;Recuerdas el concepto de &lt;strong&gt;HEAD&lt;/strong&gt;, cuando hacemos un merge y queremos devolvernos al estado anterior de ese merge podemos usar:&lt;br&gt;
&lt;code&gt;&amp;lt;destino&amp;gt;&lt;/code&gt; para este ejemplo puede ser un hash o un HEAD.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git reset --hard &amp;lt;destino&amp;gt;&lt;/code&gt;: Restablece el estado destino. Cualquier cambio en los archivos ya committed en el árbol de trabajo son descartados. En palabras simples, borra todos los commits hasta el hash/HEAD destino.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git reset --mixed&lt;/code&gt;: Restablece el estado destino. Preserva los archivos hasta 1el hash/HEAD destino pero debes hacer algo con ellos, borrarlos, eliminarlos o agregarlos nuevamente al árbol de commits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cherry pick
&lt;/h3&gt;

&lt;p&gt;Básicamente, el cherry pick es un comando que nos permite integrar, desde una branch B, un único commit a la rama destino. Esto es útil cuando tenemos una funcionalidad compartida que aun no se ha integrado en la rama destino, pero se require para poder seguir el ciclo de desarrollo.&lt;br&gt;
Otro caso de uso es cuando tenemos un hotfix por medio de un cherry pick podemos traer el cambio del hotfix a una rama destino.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S4pUa2GW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3exgITA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S4pUa2GW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3exgITA.png" alt="cherry-pick" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Uso del reflog
&lt;/h3&gt;

&lt;p&gt;El reflog es el 'diario', el journal donde se registran todas las interacciones con git.&lt;br&gt;
Es fácil de usar, pero poderoso para que podamos complementar nuestro trabajo a la hora de buscar y encontrar diferentes acciones realizadas previamente&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5_3_iiQj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/JmsRXnn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5_3_iiQj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/JmsRXnn.png" alt="reflog" width="658" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;En el siguiente tutorial veremos varios usos de este comando.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusiones
&lt;/h3&gt;

&lt;p&gt;Después de hacer este tutorial, estamos listos para iniciar el último y más retador, donde veremos más de 10 casos y situaciones a resolver con todo lo aprendido hasta ahora.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referencias
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.git-tower.com/learn/git/ebook"&gt;Git-tower&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/"&gt;Git-Oficial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lab.github.com/"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/book/es/v2"&gt;Git book&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://books.google.com.co/books/about/Version_Control_with_Git.html?id=qIucp61eqAwC&amp;amp;redir_esc=y"&gt;Version control Git - Book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>Git para todos. Parte 2 - Branches</title>
      <dc:creator>James Cardona</dc:creator>
      <pubDate>Tue, 17 May 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/jamescardona11/git-para-todos-parte-2-branches-3cae</link>
      <guid>https://dev.to/jamescardona11/git-para-todos-parte-2-branches-3cae</guid>
      <description>&lt;p&gt;Git nos facilita el trabajo proporcionando las branches, esa poderosa herramienta para poder interactuar en "sub-espacios" de trabajo.&lt;br&gt;
Con esto gestionar equipos distribuidos y crear diferentes flujos de trabajo no es un problema.&lt;br&gt;
Esta funcionalidad tiene sus consideraciones y por eso se han inventado diferentes &lt;strong&gt;workflows&lt;/strong&gt; para establecer reglas que nos ayuden a trabajar sobre un marco común para el equipo.&lt;/p&gt;


&lt;h3&gt;
  
  
  ¿Qué son las Branch?
&lt;/h3&gt;

&lt;p&gt;Una branch es espacio de memoria separado donde podemos crear, modificar y eliminar parte de nuestro trabajo sin que el espacio principal se vea afectado hasta que decidamos unir ambos espacios en uno solo.&lt;br&gt;
Su uso se extiende para poder dejar versiones 'seguras/fiables' del código, crear workflows para trabajo en equipo, hacer pruebas de concepto, solucionar errores específicos, entre otras cosas.&lt;br&gt;
Una branch nos permite independizar el trabajo y enfocarnos en pequeñas unidades de trabajo (features).&lt;/p&gt;
&lt;h3&gt;
  
  
  ¿Cómo interactuamos con ellas?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git branch &amp;lt;name&amp;gt;&lt;/code&gt;: Para crear una branch desde la 'posición' donde estamos

&lt;ul&gt;
&lt;li&gt;usa &lt;code&gt;-u&lt;/code&gt; para que la branch siga un tracking con la branch remota.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git switch &amp;lt;name&amp;gt;&lt;/code&gt;: Para cambiarnos de espacio de trabajo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git branch -m &amp;lt;new-name&amp;gt;&lt;/code&gt;: Para cambiar el nombre de la branch&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;git branch -d &amp;lt;name&amp;gt;&lt;/code&gt;: Para borrar la branch

&lt;ul&gt;
&lt;li&gt;usa &lt;code&gt;-D&lt;/code&gt; cuando quieras forzar el borrado&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  ¿Qué es el HEAD?
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a13Nj_Yb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3m3kBc6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a13Nj_Yb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/3m3kBc6.png" alt="head" width="691" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Git almacena nuestro trabajo enlazando la historia de nuestros commits por medio de &lt;em&gt;hash&lt;/em&gt;, pero para facilitarnos parte de como se visualiza o no tener que acordarnos de los &lt;em&gt;hash&lt;/em&gt; nos provee un indicador que se llama &lt;strong&gt;HEAD&lt;/strong&gt;, entonces la parte superior del historial tiene un &lt;strong&gt;HEAD~0&lt;/strong&gt;, a medida que descendemos vamos aumentando el índice: &lt;em&gt;HEAD~1&lt;/em&gt;, &lt;em&gt;HEAD~2&lt;/em&gt;, &lt;em&gt;HEAD~n&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Git siempre crea nuestras branch a partir del &lt;strong&gt;HEAD&lt;/strong&gt; donde estemos ubicados.&lt;br&gt;
Si queremos crear una branch desde una posición concreta podemos usar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;git branch &amp;lt;name&amp;gt; #hash&lt;/code&gt; o &lt;code&gt;git branch &amp;lt;name&amp;gt; #head&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cuando borramos una branch, lo que estamos haciendo es borrar el tag que apunta a esa dirección de memoria.&lt;/p&gt;
&lt;h3&gt;
  
  
  ¿Qué son los conflictos?
&lt;/h3&gt;

&lt;p&gt;Cuando unimos dos branches diferentes, git se encarga de unir la mayor cantidad de código en uno solo usando estrategias automáticas, pero cuando ambas branches hacen modificaciones sobre lines o archivos donde git no pueda decidir como es la mejor forma de resolver esas diferencias va a mostrar una alerta que se conoce como &lt;strong&gt;conflictos&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Esto es un ejemplo de un conflicto&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--06ysbNuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uSIsaUo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--06ysbNuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uSIsaUo.png" alt="diff" width="483" height="340"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  ¿Cómo se resuelven?
&lt;/h4&gt;

&lt;p&gt;Realmente es trivial lo que voy a escribir, pero simplemente eligiendo/decidiendo como unir esas diferencias.&lt;/p&gt;

&lt;p&gt;Para ver las diferencias de un archivo &lt;code&gt;git diff &amp;lt;filename&amp;gt;&lt;/code&gt;&lt;br&gt;
La recomendación para mezclar conflictos es usar una herramienta externa integrada a tu IDE de desarrollo o una GUI para git.&lt;/p&gt;
&lt;h3&gt;
  
  
  Merge vs Rebase
&lt;/h3&gt;

&lt;p&gt;Hay varias estrategias para unir branches, pero podemos decir que estás dos son las más famosas, es importante entender que no es que una sea mejor que la otra, simplemente son diferentes en su forma de como queda el historial o gráfico de commits.&lt;br&gt;
Su uso depende de las estrategias del equipo o los requisitos del proyecto.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YJaL6NsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/V5hElXV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YJaL6NsE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/V5hElXV.png" alt="mergevsrebase" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Merge
&lt;/h4&gt;

&lt;p&gt;Es una estrategia muy usada y su ejecución es sencilla, simplemente crea un nuevo punto llamado &lt;em&gt;merge commit&lt;/em&gt; donde está la unión y resultado final de la unión. Adicional, preserva el historial conectando la branch que estamos mezclando.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cvcEfbmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/kZTX9X9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cvcEfbmb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/kZTX9X9.png" alt="merge" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Rebase
&lt;/h4&gt;

&lt;p&gt;Es una estrategia no tan común y con algunas consideraciones adicionales, en la estrategia de &lt;strong&gt;merge&lt;/strong&gt; no se sobrescribe el historial, simplemente se enlaza y se inicia desde un punto nuevo llamado &lt;em&gt;merge commit&lt;/em&gt;. El &lt;strong&gt;rebase&lt;/strong&gt; si sobrescribe el historial y su forma de hacer la unión, se hace en tres pasos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;step 1:&lt;/em&gt; Busca el ancestro común de ambas branches, luego "remueve" temporalmente los commits de la &lt;em&gt;branch A (destino)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;step 2:&lt;/em&gt; Coloca cronológicamente los commits de la &lt;em&gt;branch B (origen)&lt;/em&gt; en secuencia en la &lt;em&gt;branch A (destino)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;step 3:&lt;/em&gt; Une (Rebasa) los commits de la &lt;em&gt;branch A (destino)&lt;/em&gt; después del último commit de la &lt;em&gt;branch B (origen)&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En esta secuencia se puede ver que el historial se sobrescribe y se crean uno nuevo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8VDQ3cuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/ixozRBG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8VDQ3cuE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/ixozRBG.png" alt="rebase" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advertencia&lt;/strong&gt; No usar rebase sobre commits que ya están compartidos en una branch remota&lt;/p&gt;
&lt;h3&gt;
  
  
  Git flujos de trabajo
&lt;/h3&gt;

&lt;p&gt;Ya hemos avanzado mucho aprendiendo sobre branches, pero nos falta un eslabón para que los equipos puedan trabajar ordenadamente, respetando &lt;strong&gt;reglas&lt;/strong&gt; y siguiendo flujo común, esto se conoce como Git-Workflow.&lt;/p&gt;

&lt;p&gt;Puedes crear tu propio marco de trabajo o usar uno que sea ampliamente usado por la comunidad.&lt;br&gt;
En este caso tenemos algunos de ellos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gitflow&lt;/li&gt;
&lt;li&gt;Github flow&lt;/li&gt;
&lt;li&gt;Trunk-Based-Development&lt;/li&gt;
&lt;li&gt;Git release flow&lt;/li&gt;
&lt;li&gt;Gitlab flow&lt;/li&gt;
&lt;li&gt;Master only flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos a ver la diferencias entre dos de estos.&lt;/p&gt;
&lt;h4&gt;
  
  
  Gitflow
&lt;/h4&gt;

&lt;p&gt;Este es el más conocido y el más usado por muchas empresas dada la facilidad de uso.&lt;/p&gt;

&lt;p&gt;Es un flujo para trabajos de equipos compactos, parte de la idea que creamos una branch principal (&lt;strong&gt;main&lt;/strong&gt;), es nuestra branch segura y de acá derivamos la estrategia creando branches de soporte.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Desarrollo: Features branches&lt;/li&gt;
&lt;li&gt;Pre-prod: Develop&lt;/li&gt;
&lt;li&gt;Prod: Releases branches&lt;/li&gt;
&lt;li&gt;Zona segura: main&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es útil para proyectos que tienen un ciclo de publicación programado. Un trabajo basado en publicaciones.&lt;/p&gt;
&lt;h5&gt;
  
  
  ¿Cómo funciona?
&lt;/h5&gt;

&lt;p&gt;Vamos a establecer las dos branches principales, &lt;strong&gt;Main&lt;/strong&gt; y &lt;strong&gt;Develop&lt;/strong&gt; para llevar el historial del proyecto, son branches de larga duración. La branch main se usa para almacenar el historial de publicación. La branch develop se usa para la integración de nuevos features.&lt;/p&gt;
&lt;h6&gt;
  
  
  1) Branches de features
&lt;/h6&gt;

&lt;p&gt;Son para crear un historial nuevo para pequeñas funcionalidades que se van a desarrollar en el ciclo de desarrollo. Las branches nuevas deben partir de la branch develop y cuando la feature esta terminada se debe integrar nuevamente a develop.&lt;/p&gt;
&lt;h6&gt;
  
  
  2) Branches de release
&lt;/h6&gt;

&lt;p&gt;Cuando se acerque la fecha de release o tengamos suficientes características integradas debemos bifurcar las características en una branch de release, cuando se crea esta branch ya no pueden añadirse nuevas funcionalidades a la branch de release y esta branch solo deben producirse la solución de errores(hotfix).&lt;/p&gt;

&lt;p&gt;Cuando el release esta listo se debe enviar a la branch main y adicional a la branch develop.&lt;/p&gt;
&lt;h6&gt;
  
  
  3) Branches de hotfix
&lt;/h6&gt;

&lt;p&gt;Son branches que sirven para reparar errores en producción, siempre deben salir de la branch main. Cuando se termine la corrección debe integrarse a main y a develop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m2DZxEDf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6MSdEke.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m2DZxEDf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/6MSdEke.png" alt="gitflow" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Trunk-Based Development
&lt;/h4&gt;

&lt;p&gt;Es un poco más moderno y su poder se basa en construir equipos más maduros. Donde todo se integra en una branch principal y desde ahí salen las features. Evitamos tener branches de larga duración.&lt;/p&gt;

&lt;p&gt;Desarrollo: Features branches&lt;br&gt;
Prod: Main o Tag-references&lt;/p&gt;
&lt;h6&gt;
  
  
  ¿Cómo funciona?
&lt;/h6&gt;

&lt;p&gt;Es una estrategia donde se usa una branch principal main, en esta branch todo el equipo se integra haciendo push a esta branch. La branch main-trunk se puede usar para hacer release donde se requiera, como por ejemplo a ambientes de pre-productivos, local, etc. Su veracidad y respaldo la dan los tags o etiquetas. Se dice que las branches de features solo deben durar pocos días.&lt;/p&gt;
&lt;h6&gt;
  
  
  1) ¿Qué se requiere que un equipo trabaje con TBD?
&lt;/h6&gt;

&lt;p&gt;Madurez sin esto esta estrategia se verá impactada por múltiples conflictos que a su vez se evidencia en fallos de la aplicación. Madurez personal como técnica.&lt;/p&gt;
&lt;h6&gt;
  
  
  2) ¿Cuándo usarlo?:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Si la frecuencia de release es alta, trunk based development es la estrategia adecuada.&lt;/li&gt;
&lt;li&gt;Equipos maduros y productos establecidos, con sus tiempos y fechas de release bien definidos, es probable que no lo necesiten&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4CVfTx00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/91do0rJ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4CVfTx00--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/91do0rJ.png" alt="tbd" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt; &lt;br&gt;
 &lt;br&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Conclusiones
&lt;/h3&gt;

&lt;p&gt;Esté camino, apenas empieza, hay muchas cosas por aprender y explorar, pero básicamente con este tutorial ya tienes lo necesario para gestionar tu trabajo de equipo y adicional poder proponer soluciones a la hora de trabajar con diferentes workflows.&lt;/p&gt;
&lt;h3&gt;
  
  
  Referencias
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/"&gt;Git-Oficial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://lab.github.com/"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/book/es/v2"&gt;Git book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.git-tower.com/learn/git/ebook"&gt;Git-tower&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://books.google.com.co/books/about/Version_Control_with_Git.html?id=qIucp61eqAwC&amp;amp;redir_esc=y"&gt;Version control Git - Book&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gracias por llegar hasta acá, considera dar un like, compartir y nos vemos en un próximo artículo.&lt;/p&gt;

&lt;p&gt;
  &lt;a href="https://i.giphy.com/media/lHUqlB9cPwESCr078o/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/lHUqlB9cPwESCr078o/giphy.gif" width="480" height="270"&gt;&lt;/a&gt;
&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
  </channel>
</rss>
