I iterate 2 array in a v-for with fields that have a relation

4

I want to show two arrays in a table

veran I have two arrays in the first one I have the products and the second one I have the states of the products and it has a field product_id to which it refers.

                   <table class="table">
                        <thead>
                            <tr>
                                <th>id</th>
                                <th>name</th>
                                <th>estado</th>
                            </tr>
                        </thead>
                        <tbody>
                            <tr v-for="pro in productos" :key="pro.id">
                                <td>{{pro.id}}</td>
                                <td>{{pro.name}}</td>
                                <td>{{aqui quiero mostrar el estado del segundo arry}}</td>
                            </tr>
                        </tbody>
                    </table>

These are the arrys:

 productos:[
              {id:1, name: 'gaseosa'},
              {id:2, name: 'carne'},
              {id:3, name: 'pasta'},
              {id:4, name: 'arroz'},
              {id:5, name: 'queso'},
          ],
          estadoProducto:[
              {id:1, status: 'activo', producto_id:1},
              {id:2, status: 'inactivo', producto_id:4},
              {id:3, status: 'activo', producto_id:3},
              {id:4, status: 'activo', producto_id:5},
              {id:5, status: 'inactivo', producto_id:2},
          ],

I would greatly appreciate your valuable help

    
asked by isaac josue castellanos perdom 30.12.2018 в 03:55
source

3 answers

5

My opinion is to add a computed property to not overload the template. The advisable thing is not to put too much logic in the templates.

JS

  computed: {
    productosConEstado: function () {
      // utilizando se map agrega la propiedad estado por cada elemento del array productos
      let productosConEstado = this.productos.map(p => {
        p.estado = this.estadoProducto.find( (el) => { return el.producto_id === p.id } ).status
        return p
      })
      return productosConEstado
    }
  }

HTML

  <table class="table">
    <thead>
      <tr>
        <th>id</th>
        <th>name</th>
        <th>estado</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="pro in productosConEstado" :key="pro.id">
        <td>{{pro.id}}</td>
        <td>{{pro.name}}</td>
        <td>{{pro.estado}}</td>
      </tr>
    </tbody>
  </table>
    
answered by 30.12.2018 / 17:25
source
4

It's easier if you combine the two arrangements into one. That way, you can go through the arrangement obtained with a v-for. If those arrangements are obtained with an Ajax request, the moment you receive the response from the server, you transform them into something like this:

productos:[
   {id:1, name: 'gaseosa', status: 'activo'},
   {id:2, name: 'carne', status: 'inactivo'},
   {id:3, name: 'pasta', status: 'activo'},
   {id:4, name: 'arroz', status: 'inactivo'},
   {id:5, name: 'queso', status: 'activo'}
]

Another solution, which I think is more correct and responds better to your question, is to use the "find" method for fixes.

Your code would look like this:

<tr v-for="pro in productos" :key="pro.id">
   <td>{{ pro.id }}</td>
   <td>{{ pro.name }}</td>
   <td>{{ estadoProducto.find(el => el.producto_id == pro.id).status }}</td>
</tr>

But if you have to support the infamous IE, the mentioned method is not supported by that browser. However, there is a polyfill on this page that you can apply: Array.prototype .find () and, in that case, you should replace the arrow functions with common functions. It would be like that without functions arrow:

<tr v-for="pro in productos" :key="pro.id">
   <td>{{ pro.id }}</td>
   <td>{{ pro.name }}</td>
   <td>{{ estadoProducto.find(function(el) { return el.producto_id == pro.id; } ).status }}</td>
</tr>

Greetings!

    
answered by 30.12.2018 в 04:52
3

I'll leave another answer, but Pedro's is valid.

We are simply going to do the same, but using VUE directly. in this way we do not have to add any external libraries and we do not depend on browser problems since it will only be transpiled to something compatible.

And besides, it does exactly the same thing, since the find method runs through the array and only shows the element that fulfills that condition. But what would happen if two or more comply?

 <tr v-for="pro in productos" :key="pro.id">
     <td>{{pro.id}}</td>
     <td>{{pro.name}}</td>

     <td v-for="e in estadoProducto" :key="e.id">
         <span v-if="e.producto_id = pro.id">
             {{e.status}}
         </span>
     </td>
     </tr>
    
answered by 30.12.2018 в 05:55