Async problem, Data requested don't fill a select

Hello, I’m trying to fill a SeIect form object with data from a Database in a Component Page.
I get the data, and fill an array. i console.log() the array and it show the data inside, but it’s say in the console: “value bellow was evaluated just now”… And I console.log() the lenght of the array before proceed to fill the select with the data inside of it and the lenght is just 0. So the data is inside the array after I try to fill the select…
How can I wait or something for the array filled before try to push() the data inside the Select…??
The Async drive me crazy, i don’t know how to know when the data is ready, and what things are happening after or before…

This page fills a Select with Color names and codes, to filter the events by color in another Calendar Page… This call to the calendar works when I fill the Select statically, without a Request… Now i’'m triying to fill the Select dinamically…

Thanks in advance :grin:

The code:

<template>
<div class="page">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner sliding">
      <div class="left">
        <a href="#" class="link back">
          <i class="icon icon-back"></i>
          <span class="if-not-md">Back</span>
        </a>
      </div>
      <div class="title">Formulario</div>
    </div>
  </div>
  <div class="page-content">
    <div class="block">
      <p>Texto ejemplo.</p>
    </div>
    <form>
      <ul>
        <li class="item-content item-input">
          <div class="item-media">
            <i class="icon demo-list-icon"></i>
          </div>
          <div class="item-inner">
            <div class="item-title item-label">Color</div>
            <div class="item-input-wrap input-dropdown-wrap">
              <select id="var-color" placeholder="Elige un color...">
                {{#each arrItemsColor}}
                    <option value="{{color_code}}">{{color_name}}</option>
                {{/each}}
              </select>
            </div>
          </div>
        </li>
      </ul>

      <div class="list">
        <ul>
          <li><a href="#" class="list-button" @click="signIn">Enviar</a></li>
        </ul>
        <div class="block-footer">Some text information.<br>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
      </div>
    </form>
  </div>
</div>
</template>
<script>
  return {
    data:function(){
      return {
        arrItemsColor: [],
        colores: [],
      }
    },
    methods: {
      signIn: function () {
        var $ = this.$;
        var app = this.$app;
        var router = this.$router;
        var varColor = document.getElementById("var-color").value;

        router.navigate({
          name: 'calendario2',
          params: { color: varColor },
        });
      },

      renderColors: function () {
        var self = this;
        var arrColoresActuales = self.colores;

        //******** AAAAAA
        console.log(arrColoresActuales);

        const arrItemsColor = [];

        //******** BBBBBB
        console.log("longitud: " + arrColoresActuales.length);

        if (arrColoresActuales.length) {

          arrColoresActuales.forEach(function (itmcolor) {


            arrItemsColor.push({
              color_name: itmcolor.color_name,
              color_code: itmcolor.color_code,
            });
          });
        }
        self.$setState({
          arrItemsColor: arrItemsColor,
        });
      },

      getColores:function(){
        var self = this;
        var app = self.$app;


        app.request({url:'http://myurl/myfile.php',method:'GET',dataType:'json',
          success:function(data){
            data.colores.map(function(itm){
              // console.log(" cod_color: " + itm.cod_color);
              return {
                color_code: itm.cod_color, color_name: itm.nombre_color,
              }
            }).forEach(function(itm){ self.colores.push(itm); });
            //console.log(self.colores);
          }
        });
      },
    },

    on: {
      pageInit: function (e, page) {
        var self = this;
        var app = self.$app;
        var $ = self.$;

        self.getColores();
        self.renderColors();

      },

    }
  }
</script>

In the // **** AAAAAA place I console.log() the array data, this data appears in the console log with the message: “value bellow was evaluated just now
In the // **** BBBBBB place I console.log() the array lengh
If this array is 0, this happens, dont fill the Select…

The url request give a string like this:

{ "colores" : [{ "cod_color":"e91e63", "nombre_color":"Rojo" } ,{ "cod_color":"ff9800", "nombre_color":"Naranja" } ,{ "cod_color":"2196f3", "nombre_color":"Azul" } ,{ "cod_color":"4caf50", "nombre_color":"Verde" } ] }

This code is based in the code made by @plpl in this other Question solved by him:

Maybe i need to use a Smart Select Component instead a Common Select?? An use the renderItems() function inside his on: { opened: event???

same story

your code:

self.getColores();
self.renderColors();

will execute:

  1. renderColors
  2. getColores

// template (add navbar)

<template>
<div class="page">
  <div class="page-content">
    <div class="list">
      <ul>
        <li>
          <a class="item-link smart-select">
            <select name="color">
              {{#colors}}
              <option value="{{value}}" {{#if @first}}selected{{/if}}>
                {{title}} 
              </option>
              {{/colors}}
            </select>
            <div class="item-content">
              <div class="item-inner" style="color:#{{selected}}">
                <div class="item-title">Color</div>
              </div>
            </div>
          </a>
        </li>
      </ul>
    </div>
  </div>
</div>
</template>

// script (change ‘url’)

<script>
return {
  data:function(){
    return {
      title: 'page title',
      colors: [],
      selected: null
    }
  },
  methods:{
    createSmartSelect:function(){
      var self = this;
      self.$app.smartSelect.create({
        el: self.$el.find('.smart-select'),
        openIn: 'popover',
        on:{
          close:function(s){
            console.log(s.getValue())
            self.$setState({
              selected: s.getValue()
            });
            console.log(self.selected)
          }
        }
      });
    },
    getColors:function(){
      var self = this;
      self.$app.request({url:'url',method:'GET',dataType:'json',
        success:function(data){
          self.$setState({
            colors: data.colores.map(function(itm){
              return {
                title: itm.nombre_color,
                value: itm.cod_color
              };
            })
          });
          self.createSmartSelect();
        }
      });
    }
  },
  on:{
    pageInit:function(e,page){
      this.getColors();
    }
  }
}
</script>

or try this => https://framework7.io/docs/color-picker.html#color-picker-modules

1 Like

Thanks again @plpl
And why the app execute in this order?
Your code works fine…
I need to study your code below (post#3) to understad how its works to make the app do the things in the right order…
I don’t know why this execute first the renderColors if i’ve put the getColors first…
I study programming 20 years ago… I worked 2 years 18 years ago… I’ve been without coding all this time… so things have been changed a lot :sweat_smile:, but i’m going to do this app :muscle: :rofl:

I’m going to try to make the code works without the Smart Select, with a common Select object. But if i don’t get it i will use the SmartSelect.

My app need to have some filter options, i’m beggining with only a Select to learn, and then i will need to add the other Fields from the database and Filter options… Even multiple selects

Thanks :grinning:

I’m using the Color in the database to filter the results… so i can’t use the color picker here, because is very difficult that the user select the same color in the database to filter the results… i need to restrict the colors to those existing in the database…
I can use this picker to create the colors in other page to add them in the database to add events in that color, but not to make the filter page…
Anyway the color will be assigned to a category, will not be used by the color itself but assigned to a category with a name

app.request({
  success:function(data){
    console.log(1);
  }
});
console.log(2);

is equivalent to:

setTimeout(function(){
  console.log(1);
},0);
console.log(2);

#output in both cases:
2
1

1 Like

use the “Wheel color”
unless you want to reinvent it

if you want only specific color
you can use ‘palette’

app.colorPicker.create({
  modules: ['palette'],
  //palette: ['#FFEBEE', '#FFCDD2']
  palette: data.colores.map(function(itm){ return '#'+itm.cod_color; })
});
1 Like

Thanks @plpl, your link about Syncronous and asyncronous request and all your help has been great!!! Really helpful!!!
:+1: :+1: :+1: :partying_face: :partying_face: :partying_face: