1

Necesito ordenar mi JSON por id ascendentemente, por la consola me lo saca ordenado, pero a la hora de pintarlo me lo despinta, sabéis como puedo hacerlo?

EDITO

Ya se de donde viene el error y por que, pero no se solucionarlo a ver si alguien puede hecharme una mano, el error viene del keyvalue lo está ordenando correctamente pero cuando llega al número 10 lo coge como si fuese un 1 entonces lo pone debajo del 1 cuando llega el 11 lo pone en tercera posición porque lo coge como otro 1 y así sucesivamente...

<ng-template #bloqueTemplate let-bloque='obj'>
    <mat-expansion-panel class="bloque">
        <mat-expansion-panel-header>{{bloque.titulo}}</mat-expansion-panel-header>
        <div *ngFor="let pregunta of bloque.preguntas | keyvalue">
        Hola
        {{ bloque.id}}
            <ng-container [ngTemplateOutlet]="preguntaTemplate" [ngTemplateOutletContext]="{obj:pregunta.value, id: bloque.id}">
            </ng-container>
        </div>
    </mat-expansion-panel>
    <div>
        <canvas id="{{bloque.id}}">
        </canvas>
    </div>
</ng-template>

No se si puede que esté en esta parte de código

            <div *ngFor="let item of cuestionario.content | keyvalue">
            <ng-container [ngTemplateOutlet]="isPregunta(item.value) ? preguntaTemplate : bloqueTemplate" [ngTemplateOutletContext]="{obj:item.value, id: isPregunta(item.value) ? 0 : item.value.id}">
            </ng-container>
        </div>  

cuestionario.content

   initFormControl() {
    for(var index in this.cuestionario.content) {
      var item = this.cuestionario.content[index];

      if(this.isPregunta(item)) {
        this.crearFormControls(item, 0);
      } else {
        for(var preg of item.preguntas) {
          this.crearFormControls(preg, item.id);
        }
      }
    }

    this.done = true;
    this.getGraphsData()
  }

introducir la descripción de la imagen aquí

  • 1
    [JSON != Objeto en Javascript](https://es.stackoverflow.com/questions/164943/cu%c3%a1l-es-la-diferencia-entre-json-y-un-objeto-en-javascript) – Pablo Lozano Aug 01 '19 at 09:41
  • ¿Puedes poner un ejemplo de lo que hay en `cuestionario.content`? Si es un array puedes ordenarlo fácilmente con el método `sort` – Pablo Lozano Aug 01 '19 at 09:42
  • Por supuesto que puedo @PabloLozano `initFormControl() { for(var index in this.cuestionario.content) { var item = this.cuestionario.content[index]; if(this.isPregunta(item)) { this.crearFormControls(item, 0); } else { for(var preg of item.preguntas) { this.crearFormControls(preg, item.id); } } } this.done = true; this.getGraphsData() }` – Miguel Ángel Martín Aug 01 '19 at 10:06
  • 2
    Por favor, usa [edit] para añadir datos a la pregunta. De todos modos me refiero a los datos que hay en la variable, no al código en sí. – Pablo Lozano Aug 01 '19 at 10:13
  • @PabloLozano te refieres a eso? – Miguel Ángel Martín Aug 01 '19 at 10:28
  • No me cuadra con el código: si cada entrada es un item, no hay campo `value`. Hay id, titulo, visibleCliente... y no parece ser un array, sino un objeto con propiedades con clave numérica – Pablo Lozano Aug 01 '19 at 10:54
  • Si, es un poco raro @PabloLozano – Miguel Ángel Martín Aug 01 '19 at 11:01

4 Answers4

1

No es mejor usar el pipe siguiente??

*ngFor="let item of items| orderBy:fieldName"

Espero que te ayude

BetaM
  • 30,571
  • 7
  • 32
  • 50
Luiggi
  • 211
  • 1
  • 7
  • En lugar de preguntar yo agregaría una explicación de cómo esto soluciona el problema del OP – BetaM Aug 05 '19 at 13:35
  • Lo que no me entra en la cabeza es si en el objeto me lo muestra ordenado por que a la hora de pintarlo, lo pinta desordenado – Miguel Ángel Martín Aug 06 '19 at 06:43
  • Lo suyo es utilizar un pipe: te dejo el ejemplo en: https://stackblitz.com/edit/sort-with-pipe?file=src%2Fapp%2Fhello.component.ts – Luiggi Aug 06 '19 at 07:07
  • @Miguel Ángel Martín : Te he actualizado y parametrizado el pipe para que así puedas ordenar la lista por el campo que desees: https://stackblitz.com/edit/sort-with-pipe?file=src%2Fapp%2Fapp.component.ts – Luiggi Aug 06 '19 at 07:29
  • @Luiggi me tira el siguiente error `The pipe 'sort' could not be found ("expansion-panel-header>{{bloque.titulo}}` – Miguel Ángel Martín Aug 06 '19 at 07:42
  • Añadí el código abajo, míralo! – Luiggi Aug 06 '19 at 10:04
0

te agrego el código.

  1. Generamos un pipe como este:
import { Pipe, PipeTransform } from "@angular/core";

@Pipe({
  name: "sort"
})
export class SortPipe implements PipeTransform {
    transform(array: Array<any>, args: string): Array<any> {
        return array.sort((a: any, b: any) => {
            if (a[args] < b[args]) {
                return -1;
            } else if (a[args] > b[args]) {
                return 1;
            } else {
                return 0;
            }
        });
    }
}
  1. Añadimos el Pipe al app.module o tu módulo específico
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';
import { SortPipe } from './sort.pipe';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent, SortPipe ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }
  1. En el componente asumimos que tenmos una lista como esta:
import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  list:any[] = [
    {id:2,name:'d'},
    {id:5,name:'a'},
    {id:4,name:'b'},
    {id:1,name:'a'},
    {id:3,name:'z'},
    {id:6,name:'c'},
  ]
}
  1. Solo nos queda añadir el pipe a nuestro ngfor:
   <label>lista ordenada Sort</label>
    <div *ngFor="let item of list | sort: 'id'">{{item.id}}</div>

Cualquier duda lo miramos

Luiggi
  • 211
  • 1
  • 7
0

Al final lo solucione de esta manera.

Como mi objeto ya estaba ordenado lo que hice fue decirle al keyvalue que no haga nada básicamente por lo que cree una función retornando 0 y la llame desde el keyvalue

 <div *ngFor="let item of cuestionario.content | keyvalue : returnZero">
     <ng-container [ngTemplateOutlet]="isPregunta(item.value) ? preguntaTemplate : bloqueTemplate" [ngTemplateOutletContext]="{obj:item.value, id: isPregunta(item.value) ? 1 : item.value.id}">
     </ng-container>
 </div>

Y en la función

  returnZero() {
    return 0
  }
-1

Un ejemplo con Javascript sería así:

let items = [
  { name: 'Edward', id: 4},
  { name: 'Sharpe', id: 5},
  { name: 'And', id: 3},
  { name: 'The', id: 2},
  { name: 'Magnetic', id: 1},
  { name: 'Zeros', id: 10 }
];

items.sort((a,b) => Number(a.id) - Number(b.id));

El resultado sería el siguiente:

[
  { name: 'Magnetic', id: 1},
  { name: 'The', id: 2},
  { name: 'And', id: 3},
  { name: 'Edward', id: 4},
  { name: 'Sharpe', id: 5},
  { name: 'Zeros', id: 10 }
]