<?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: Alfredo Bautista 💙 #FlutterConf20</title>
    <description>The latest articles on DEV Community by Alfredo Bautista 💙 #FlutterConf20 (@alfredobs97).</description>
    <link>https://dev.to/alfredobs97</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%2F350926%2Fbf374e70-67f4-4185-ba33-fddc3608fdad.jpg</url>
      <title>DEV Community: Alfredo Bautista 💙 #FlutterConf20</title>
      <link>https://dev.to/alfredobs97</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alfredobs97"/>
    <language>en</language>
    <item>
      <title>Conociendo las listas en Dart</title>
      <dc:creator>Alfredo Bautista 💙 #FlutterConf20</dc:creator>
      <pubDate>Mon, 06 Apr 2020 15:15:25 +0000</pubDate>
      <link>https://dev.to/alfredobs97/conociendo-las-listas-en-dart-401m</link>
      <guid>https://dev.to/alfredobs97/conociendo-las-listas-en-dart-401m</guid>
      <description>&lt;p&gt;¡Buenas a todos! En este post conoceremos un poco más la clase List para trabajar de forma más sencilla y eficiente con ella.&lt;/p&gt;

&lt;h1&gt;
  
  
  Single Level of Abstraction (SLA) 🔮
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;SLA&lt;/strong&gt; o principio de &lt;strong&gt;mismo nivel de abstracción&lt;/strong&gt; nos indica, que en un código limpio, no debe mezclar instrucciones de alto nivel con instrucciones de bajo nivel en la implementación de nuestra lógica. Esta norma genera código que es legible y entendible al no mezclar niveles de profundidad dentro de un mismo método o fragmento de código.&lt;/p&gt;

&lt;p&gt;Podemos diferenciar entre estructuras de bajo nivel o alto nivel cuando nuestro código debe utilizar índices numéricos, bucles for y while, comprobación manual de propiedades, etc.&lt;/p&gt;

&lt;p&gt;Estructuras de alto nivel pueden ser métodos descriptivos que cumplan una función específica como la búsqueda por nombre, la ordenación por un criterio o el filtrado de datos.&lt;/p&gt;

&lt;p&gt;Un ejemplo claro de estructuras de bajo nivel es la implementación de una búsqueda por nombre de un usuario, en un Array, usando bucles con índices y redirección de flujo. En este caso en Java.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight java"&gt;&lt;code&gt;
 &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;userByName&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

       &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
             &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
                &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En los lenguajes de alto nivel ya tenemos métodos, creados por los desarrolladores del lenguaje, para que podamos simplificar estos procesos y escribir todo nuestro código en un nivel alto de abstracción, sin tener que trabajar con estructuras de bajo nivel. Aquí tenemos una búsqueda, por nombre de usuario, en una lista usando estructuras de alto nivel, escrito en Dart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="nf"&gt;userByName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;firstWhere&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Métodos útiles de Listas de Dart
&lt;/h1&gt;

&lt;p&gt;Ahora que ya hemos visto porque utilizar funcionalidades del propio lenguaje que tener que codificarlo nosotros, vamos a ver qué métodos útiles nos da List en Dart.&lt;/p&gt;

&lt;h2&gt;
  
  
  map
&lt;/h2&gt;

&lt;p&gt;El método map nos devuelve un nuevo iterable, con el resultado que le asignemos en el &lt;em&gt;callback&lt;/em&gt;, que le pasamos al método. En este caso, queremos una lista que nos indique: &lt;strong&gt;Username: + nombre del usuario&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nameOfUsers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;'Username: '&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameOfUsers&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [Username: Alfredo, Username: pepito, Username: Otro]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  where y firstWhere
&lt;/h2&gt;

&lt;p&gt;Los métodos de búsqueda o filtro where y firstWhere nos devuelven un iterable o ítem, que cumpla con el criterio indicado en la &lt;em&gt;callback&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;usersOlderThan18&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;firstUserOlderThan18&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;firstWhere&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  contains
&lt;/h2&gt;

&lt;p&gt;Este método nos devuelve un &lt;em&gt;boolean&lt;/em&gt; indicando, si la lista contiene el mismo ítem que le pasamos por parámetro. Es importante recalcar que &lt;strong&gt;debe ser la misma instancia&lt;/strong&gt;, no un ítem que sea igual.&lt;/p&gt;

&lt;p&gt;Por ejemplo, este código nos devuelve &lt;em&gt;false&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Pepito'&lt;/span&gt;&lt;span class="o"&gt;)];&lt;/span&gt;

 &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;// false;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;este código nos devuelve &lt;em&gt;true&lt;/em&gt; al ser la misma instancia&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;usuario&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Usuario'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;usuario&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// true;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  any
&lt;/h2&gt;

&lt;p&gt;Nos devuelve un &lt;em&gt;boolean&lt;/em&gt;, indicando si algún ítem cumple el criterio especificado en la &lt;em&gt;callback&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;any&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  remove, removeAt, removeWhere
&lt;/h2&gt;

&lt;p&gt;Estos métodos nos sirven para eliminar ítems de nuestra lista, es importante recalcar que &lt;strong&gt;muta&lt;/strong&gt; o modifica la lista original, algunos ejemplos de ello:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;remove&lt;/strong&gt;: Nos permite eliminar el ítem pasándole la misma instancia por parámetro, como hemos visto anteriormente, debe ser &lt;strong&gt;el mismo ítem&lt;/strong&gt;, no uno igual.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="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;userTemp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userTemp&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;removeAt&lt;/strong&gt;: Nos permite eliminar el ítem sabiendo su posición, &lt;strong&gt;sin necesidad de tener la instancia del mismo&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;removeWhere&lt;/strong&gt;: Este último nos permite eliminar el ítem sin necesidad de tener su instancia o conocer su posición. Eliminará todos los elementos que cumplan con la condición de la &lt;em&gt;callback&lt;/em&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeWhere&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  sort
&lt;/h2&gt;

&lt;p&gt;Este método nos permite ordenar las listas, para ello utiliza &lt;em&gt;Comparator&lt;/em&gt; si el ítem lo contiene o podemos pasarle en la &lt;em&gt;callback&lt;/em&gt; la función que va a utilizar para saber cómo ordenar los elementos.&lt;/p&gt;

&lt;p&gt;Hay clases del lenguaje que ya contienen un comparador y puede ordenar las listas automáticamente, como por ejemplos los números.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// [-11, 2, 13]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Si no tenemos &lt;em&gt;Comparator&lt;/em&gt; implementado debemos retornar un &lt;em&gt;integer&lt;/em&gt; en la &lt;em&gt;callback&lt;/em&gt; con la siguiente especificación:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sí se debe ordenar por encima, un valor positivo.&lt;/li&gt;
&lt;li&gt;Sí son iguales un 0.&lt;/li&gt;
&lt;li&gt;Sí es menor un valor negativo.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Pepito'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Otro'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;)];&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;userA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userB&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;userB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [Otro, Alfredo, Pepito]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Si queremos que estén ordenados de menor a mayor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;
&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;userA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;userB&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;userB&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;age&lt;/span&gt; &lt;span class="o"&gt;?&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;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [Pepito, Alfredo, Otro]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  indexWhere
&lt;/h2&gt;

&lt;p&gt;Este método nos devuelve el indice del ítem que cumpla la condición del &lt;em&gt;callback&lt;/em&gt;, es muy útil para buscar cuándo no tenemos la instancia del objeto y queremos su posición.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;indexWhere&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Propiedades útiles
&lt;/h1&gt;

&lt;p&gt;En la clase List tenemos propiedades interesantes como &lt;em&gt;reversed&lt;/em&gt; que nos devuelve un &lt;em&gt;iterador&lt;/em&gt; con el contenido de la lista en un orden inverso.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;
&lt;span class="n"&gt;List&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;usersInverted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reversed&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toList&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="c1"&gt;// Alfredo, Pepito, Otro&lt;/span&gt;
&lt;span class="n"&gt;usersInverted&lt;/span&gt; &lt;span class="c1"&gt;// Otro, Pepito, Alfredo&lt;/span&gt;

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



&lt;p&gt;U otras como &lt;em&gt;isEmpty&lt;/em&gt; o &lt;em&gt;isNotEmpty&lt;/em&gt; que nos devuelve un &lt;em&gt;boolean&lt;/em&gt;, indicando si la lista contiene algún elemento.&lt;/p&gt;

&lt;h1&gt;
  
  
  💡 Tip: construir una lista inmutable
&lt;/h1&gt;

&lt;p&gt;En Dart, tenemos el &lt;em&gt;keyword&lt;/em&gt; &lt;strong&gt;final&lt;/strong&gt; que nos permite indicar que una variable no va a cambiar de tipo, pero esto no nos asegura la &lt;strong&gt;integridad&lt;/strong&gt; de una lista. Al añadir o quitar un elemento la lista sigue teniendo el mismo tipo aunque su contenido haya cambiado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Pepito'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Otro'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;)];&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Nuevo'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="c1"&gt;// [Alfredo, Pepito, Otro, Nuevo];&lt;/span&gt;

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



&lt;p&gt;Para evitar esto tenemos el constructor &lt;em&gt;List.unmodifiable&lt;/em&gt; que restringe que nuestra lista no permita añadir o remover elementos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;unmodifiable&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Alfredo'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Pepito'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Otro'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;)]);&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;name:&lt;/span&gt; &lt;span class="s"&gt;'Nuevo'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nl"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Uncaught Error: Unsupported operation: add&lt;/span&gt;

&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;removeAt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Uncaught Error: Unsupported operation: removeAt&lt;/span&gt;

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



&lt;h1&gt;
  
  
  Resumen
&lt;/h1&gt;

&lt;p&gt;Con estos pocos métodos y utilidades podremos trabajar de una forma más rápida y generando código sencillo de leer y mantener usando las listas.&lt;/p&gt;

&lt;p&gt;En este &lt;a href="https://api.dart.dev/stable/2.7.2/dart-core/List-class.html"&gt;enlace&lt;/a&gt; os dejo toda la documentación de la clase List en el momento de escribir el post.&lt;/p&gt;

&lt;p&gt;Recordad que usando &lt;em&gt;extensions methods&lt;/em&gt; introducidos en Dart 2.7 podemos implementar nuestros propios métodos en la clase List y así mejorar la simplicidad de nuestro código, os dejo este &lt;a href="https://dart.dev/guides/language/extension-methods"&gt;enlace&lt;/a&gt; por si no conocéis las extensiones en Dart.&lt;/p&gt;

&lt;p&gt;¡Un saludo y hasta la próxima!&lt;/p&gt;

</description>
      <category>dart</category>
      <category>list</category>
      <category>tutorial</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Deploy NestJS en Heroku Dyno</title>
      <dc:creator>Alfredo Bautista 💙 #FlutterConf20</dc:creator>
      <pubDate>Sun, 29 Mar 2020 16:13:53 +0000</pubDate>
      <link>https://dev.to/alfredobs97/deploy-nestjs-en-heroku-dyno-3a54</link>
      <guid>https://dev.to/alfredobs97/deploy-nestjs-en-heroku-dyno-3a54</guid>
      <description>&lt;p&gt;¡Buenas a todos! En este post vamos a ver como desplegar nuestra aplicación hecha usando &lt;a href="https://nestjs.com/"&gt;NestJS&lt;/a&gt; en heroku y con una base de datos MySQL en otro proveedor.&lt;/p&gt;

&lt;h1&gt;
  
  
  NestJS
&lt;/h1&gt;

&lt;p&gt;¿Que es NestJS? Es un framework sobre NodeJS que usa TypeScript. Trabaja a través de decoradores, tiene inyección de dependencias «inspirada» en Angular y permite modularizar nuestras aplicaciones.&lt;/p&gt;

&lt;p&gt;En resumidas cuentas, es un Framework que, a través de sus herramientas, nos permite un desarrollo más ágil de nuestro backend. Tiene una gran &lt;a href="https://docs.nestjs.com/"&gt;documentación&lt;/a&gt; y muchos &lt;a href="https://github.com/nestjs/nest/tree/master/sample"&gt;ejemplos prácticos.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Si queréis conocer más de él, os recomiendo la charla de &lt;a href="https://dev.to/carlillo"&gt;Carlos Caballero&lt;/a&gt; en el DevFest de Málaga, donde explica bastantes conceptos del framework. &lt;a href="https://www.youtube.com/watch?v=5dNzU2SqOwk&amp;amp;list=PLKxa4AIfm4pVLH1X6jMju19CKpgVcOh7G&amp;amp;index=20"&gt;Aquí&lt;/a&gt; tenéis el vídeo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Heroku
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://dashboard.heroku.com/apps"&gt;Heroku&lt;/a&gt; es una plataforma de cloud computing donde puedes alquilar servidores para poder desplegar tus aplicaciones. Tiene un producto llamado Heroku dyno donde nos provee de instancias gratuitas para el despliegue de aplicaciones con &lt;a href="https://devcenter.heroku.com/articles/buildpacks"&gt;Buildpacks&lt;/a&gt;. Los cuales tienen una configuración básica por lenguaje para el despliegue de las aplicaciones.&lt;/p&gt;

&lt;p&gt;Tenéis toda la información &lt;a href="https://www.heroku.com/dynos"&gt;aquí.&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  ¿Porque he usado Heroku?
&lt;/h1&gt;

&lt;p&gt;En mi caso, voy a desplegar un proyecto que no va a producción, es un proyecto académico y por lo tanto me viene mejor que el despliegue sea gratuito.&lt;/p&gt;

&lt;p&gt;El "problema" viene cuando quieres desplegar además una base de datos. Heroku tiene &lt;strong&gt;add-ons&lt;/strong&gt;, que nos permite desplegar complementos a nuestros servidores. Para desplegar una base de datos SQL tenemos &lt;a href="https://elements.heroku.com/addons/cleardb"&gt;ClearDB&lt;/a&gt; que tiene un plan gratuito pero necesita la introducción de una tarjeta de crédito. Por lo que buscando encontré esta &lt;a href="https://remotemysql.com/"&gt;web&lt;/a&gt; que nos permite tener varias bases de datos MySQL gratuitas en la nube.&lt;/p&gt;

&lt;h1&gt;
  
  
  Manos a la obra
&lt;/h1&gt;

&lt;p&gt;NestJS al estar basado en NodeJS podemos seguir el &lt;a href="https://devcenter.heroku.com/articles/getting-started-with-nodejs"&gt;tutorial&lt;/a&gt; de heroku para el despliegue de aplicaciones hechas en NodeJS con algunos cambios que veremos a continuación.&lt;/p&gt;

&lt;h3&gt;
  
  
  Desplegar nuestro código
&lt;/h3&gt;

&lt;p&gt;Para subir nuestro código a la instancia que hayamos creado, debemos crear un repositorio local y añadir los cambios de nuestros ficheros. Después de ejecutar el comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;heroku create
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Nos habrá creado una rama remota donde podremos subir nuestros cambios al repositorio que ha creado Heroku y el que usará para descargar nuestro código en nuestro servidor.&lt;/p&gt;

&lt;p&gt;Un pequeño tip es que podéis elegir el dns que va a usar nuestra aplicación indicando un nombre a continuación de heroku create. Si está libre nos dejará usarlo y si no, nos pedirá que introduzcamos otro. De todas formas este nombre siempre puede ser cambiado.&lt;/p&gt;

&lt;h3&gt;
  
  
  Variables de entorno
&lt;/h3&gt;

&lt;p&gt;Debemos conocer que Heroku hará un mapeo de puertos para que nuestra aplicación sea accesible desde el exterior, por lo que no podremos definir de forma estática el puerto por el que escuchará nuestra aplicación. En JS podemos solucionarlo con esta condicional:&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Que nos permitirá mantener nuestro puerto de desarrollo y cogerá dinámicamente el puerto que le asigne Heroku.&lt;/p&gt;

&lt;p&gt;Siguiendo con las variables de entorno debemos también configurar nuestra aplicación, que puede ser de forma estática o dinámica.&lt;/p&gt;

&lt;p&gt;En el caso de elegir dinámica, por su flexibilidad, disponemos de una instrucción del CLI de Heroku que nos permite añadir variables de entorno a nuestro despliegue, en el caso de utilizar por ejemplo &lt;a href="https://typeorm.io/#/"&gt;TypeORM&lt;/a&gt; en nuestro NestJS podriamos definir algo así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;heroku config:set &lt;span class="nv"&gt;TYPEORM_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;user &lt;span class="nv"&gt;TYPEORM_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;pass
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;O desde nuestro perfil de administración de nuestro despliegue, en el apartado de Settings &amp;gt; Config Vars.&lt;/p&gt;

&lt;h3&gt;
  
  
  Procfile
&lt;/h3&gt;

&lt;p&gt;Procfile es el fichero que usa Heroku para conocer que comandos debe ejecutar en el contenedor para iniciar nuestra aplicación. En nuestro caso, con NestJS, en el package.json, contiene la siguiente línea:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start:prod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node dist/main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;...&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;Que es el que debemos indicar en nuestro Procfile, que es el comando que arrancará nuestro servidor en modo producción.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web: npm run start:prod
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Con esta simple instrucción, Heroku instalará los paquetes necesarios y a continuación ejecutará ese comando para iniciar el servidor. En este fichero podemos indicar cualquier comando o la ejecución de algun fichero.&lt;/p&gt;

&lt;h3&gt;
  
  
  Escalamos el servidor
&lt;/h3&gt;

&lt;p&gt;Para publicar nuestro servidor,el CLI de Heroku nos trae el siguiente comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;heroku ps:scale &lt;span class="nv"&gt;web&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Con el que podremos escalar las instancias de nuestros servidores, en este caso que es gratuita solo podemos escalar a una instancia.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conexión con la base de datos
&lt;/h3&gt;

&lt;p&gt;Con los pasos anteriores ya tendremos nuestra aplicación desplegada y accesible, pero nos falta la conexión con la base de datos para que sea totalmente funcional. Para ello vamos a la web de &lt;a href="https://remotemysql.com/"&gt;remotemysql.com&lt;/a&gt; y creamos un perfil. Tened en cuenta que necesitamos confirmar el correo.&lt;/p&gt;

&lt;p&gt;A continuación, procedemos a crear una base de datos y nos dará credenciales y dirección para que podamos acceder a ella. Esta información deberemos introducirlas en nuestras variables de entorno o estáticamente en la configuración del servidor para que se puedan comunicar.&lt;/p&gt;

&lt;h1&gt;
  
  
  Limitaciones
&lt;/h1&gt;

&lt;p&gt;Tanto en la plataforma de Heroku como en la plataforma de mysql remote tienen algunas limitaciones que debemos tener en cuenta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;En heroku, después de 30 minutos de inactividad, nuestra aplicación entrará en modo reposo y será activada cuando haya una nueva petición. En aplicaciones pesadas, el tiempo de carga de nuevo del servidor puede ser desesperante.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Solo 2 procesos por instancia en Heroku Dyno.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RemoteMysql solo permite un tamaño máximo de 5 MB por lo que puede ser muy corto dependiendo del contexto de la aplicación&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ninguna configuración en el servidor tanto de Heroku como de RemoteMysql&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Ventajas
&lt;/h1&gt;

&lt;p&gt;Como gran ventaja, esta combinación de servicios nos puede proporcionar un despliegue de una aplicación no profesional de forma gratuita y usable sin la necesidad de gestión de servidores o configuración de dominios.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resumen
&lt;/h1&gt;

&lt;p&gt;Como resumen global, diría que estas dos plataformas nos dan una gran oportunidad para que aplicaciones normalmente probadas y desarrolladas en local puedan ser accesible por más personas y compartidas de una forma mucho más sencilla. Es una gran opción para proyectos de aprendizaje y proyectos que estén empezando.&lt;/p&gt;

&lt;p&gt;¡Un saludo a todos y nos vemos en la próxima!&lt;/p&gt;

</description>
      <category>heroku</category>
      <category>nestjs</category>
      <category>javascript</category>
      <category>cloud</category>
    </item>
    <item>
      <title>NoSQL en Flutter</title>
      <dc:creator>Alfredo Bautista 💙 #FlutterConf20</dc:creator>
      <pubDate>Fri, 27 Mar 2020 17:20:27 +0000</pubDate>
      <link>https://dev.to/alfredobs97/nosql-en-flutter-450p</link>
      <guid>https://dev.to/alfredobs97/nosql-en-flutter-450p</guid>
      <description>&lt;p&gt;¡Buenas a todos! En este post veremos como usar una base de datos NoSQL en Flutter para guardar información de forma persistente.&lt;/p&gt;

&lt;h1&gt;
  
  
  SharedPreferences vs NoSQL databases
&lt;/h1&gt;

&lt;p&gt;Muchos que hayáis estado trabajando/jugando con Flutter conoceréis que se recomienda el uso del paquete &lt;a href="https://pub.dev/packages/shared_preferences"&gt;shared_Preferences&lt;/a&gt; para guardar información en formato &lt;strong&gt;clave-valor&lt;/strong&gt; del usuario.&lt;/p&gt;

&lt;p&gt;En mi caso, trabajando en un proyecto para utilizar Flutter en Mobile, web y desktop, encontré un problema para usarlo. En SO Linux no está soportado todavía por lo que debía encontrar otra solución. En ese momento encontré Sembast.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sembast
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/sembast"&gt;Sembast&lt;/a&gt; es un paquete que nos permite trabajar con bases de datos NoSQL. Este paquete tiene bastantes versiones estables y un buen rating global sobre la estabilidad del mismo.&lt;/p&gt;

&lt;p&gt;Para instalarlo únicamente deberemos añadirlo en nuestro pubspec.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;sembast&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^2.3.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Planteamiento del problema
&lt;/h1&gt;

&lt;p&gt;En mi aplicación necesitaba guardar el token de autentificación del usuario al hacer login y poder recuperarlo por cada petición que tuviera que hacer al backend.&lt;/p&gt;

&lt;h1&gt;
  
  
  Sembast en Web
&lt;/h1&gt;

&lt;p&gt;En el día que escribo el artículo sembast tiene un paquete independiente para web pero que no voy a utilizar porque no permite la elección de la clave para guardar datos, debes recoger la clave al guardar el dato y usarla cuando quieras recuperarlo. Por esta razón voy a usar shared_preferences o sembast dependiendo de la plataforma donde corre.&lt;/p&gt;

&lt;h1&gt;
  
  
  Utilización
&lt;/h1&gt;

&lt;p&gt;Este paquete nos provee de métodos para el acceso y guardado de datos NoSQL. En mi caso, he creado una clase TokenProvider estática para poder acceder al token y guardarlo sin tener que estar creando instancias del mismo y a la vez permitiendo diferenciar la plataforma donde corre y elegir que paquete usar. Empezamos indicando el fichero donde va a guardar la información.&lt;br&gt;
&lt;/p&gt;

&lt;div class="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:sembast/sembast.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;'package:sembast/sembast_io.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;'package:shared_preferences/shared_preferences.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;'package:flutter/foundation.dart'&lt;/span&gt; &lt;span class="kd"&gt;show&lt;/span&gt; &lt;span class="n"&gt;kIsWeb&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;TokenProvicer&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dbPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;'token.db'&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DatabaseFactory&lt;/span&gt; &lt;span class="n"&gt;dbFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;databaseFactoryIo&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Con esto tenemos indicado donde va a guardar la información y un objeto propio del paquete que nos permite trabajar con las bases de datos que le indiquemos.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guardar el token
&lt;/h3&gt;

&lt;p&gt;Para guardar el token simplemente he creado un método que recibe el token como String, abre una "conexión" a la base de datos, ya que es en local, y obtiene un &lt;em&gt;store&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Teniendo ya nuestra colección o &lt;em&gt;store&lt;/em&gt; podemos proceder a guardar el token de forma asíncrona. El paquete nos proporciona un método record donde indicaremos su clave y con el método put indicamos su base de datos y lo que queremos guardar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;__saveTokenMobilDesktop&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;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Database&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dbFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbPath&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StoreRef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En el caso de correr en web y no poder utilizar este paquete&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;__saveTokenWeb&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;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SharedPreferences&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;SharedPreferences&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Y el método que expone y decide cómo guardar el token&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;saveToken&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;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;kIsWeb&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;__saveTokenWeb&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;__saveTokenMobilDesktop&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Recuperar el token
&lt;/h3&gt;

&lt;p&gt;Teniendo la información guardada, únicamente debemos acceder a ella para poder leer el token y hacer las peticiones. En este caso, creamos otro método que no recibe parámetros y devuelve el token con el que vamos a hacer la petición.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;__loadTokenMobilDesktop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Database&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dbFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openDatabase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dbPath&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;StoreRef&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;main&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&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="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En el caso de usar shared_preferences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;__loadTokenWeb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SharedPreferences&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;SharedPreferences&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;prefs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'token'&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Y el método que expone y decide.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;loadToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;kIsWeb&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;__loadTokenWeb&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;__loadTokenMobilDesktop&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Uso en nuestra aplicación
&lt;/h3&gt;

&lt;p&gt;Teniendo la clase creada, solo debemos referenciarla cuando vayamos a guardar el token, por ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;loginProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;TokenProvicer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;saveToken&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginProvider&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Y donde vayamos a hacer la petición.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;TokenProvicer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;loadToken&lt;/span&gt;&lt;span class="o"&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="n"&gt;await&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&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;endPoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;headers:&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s"&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;$token&lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;Sembast es un paquete muy sencillo y estable para el manejo de bases de datos NoSQL aunque tenga la limitación de que en su parte web todavía no ofrece las mismas funcionalidades que en Mobile o Desktop.&lt;/p&gt;

&lt;p&gt;Os animo a echarle un vistazo en su &lt;a href="https://github.com/tekartik/sembast.dart"&gt;repo&lt;/a&gt; donde encontraréis muchos más ejemplos y características del paquete. También agradecer a la organización que ha creado y mantiene el paquete &lt;a href="http://www.tekartik.com/"&gt;tekatrik&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;¡Un saludo y hasta la próxima!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>nosql</category>
      <category>async</category>
    </item>
  </channel>
</rss>
