javascript - Reemplazar un setTimeout() en un Formulario Reactivo de Angular con un Observable
Quiero reemplazar un setTimeout() con un Observable en un formulario reactivo de Angular.
Tengo un componente nieto que sirve a una sección de un formulario reactivo más grande, recibe un arreglo de objetos de datos desde un endpoint de API, empaqueta esos datos en un Form Array y los envía al formulario. Esto funciona bien.
El problema es que la naturaleza asincrónica de nuestros endpoints de API hace que los datos del formulario de este componente nieto se muestren con datos antiguos antes de que los nuevos datos puedan inicializarse, limpiar los datos antiguos y volver a llenar los datos nuevos. Hemos resuelto esto con un setTimeout() de 500 ms. Funciona bien en el front-end.
El problema es que el setTimeout() está causando problemas con nuestras pruebas e2e fallando porque completa la prueba antes de que los datos se carguen. Además, un tiempo de espera no es una solución a largo plazo para este problema asincrónico... especialmente si los datos ocasionalmente podrían tardar más de 1/2 segundo (no es un caso usual, pero definitivamente plausible).
Espero reemplazar mi timeout con un observable como una mejor solución que no bloquee nuestras pruebas y pueda manejar la asincronía de manera mucho más segura. El problema es que no puedo hacer que el observable funcione y todavía soy un principiante en RxJS.
Aquí está la función original con el tiempo de espera que se está ejecutando actualmente:
setTimeout(() => {
this.dataRow = [];
for (let item of this.data.row) {
this.dataRow.push(item);
}
}, 500);
Aquí está mi intento de recrear con un Observable:
this.dataRow = [];
this.dataEmitter = from(this.data.row).pipe(delay(1000)).subscribe(data => this.dataRow.push(data);)
Mi código crea un flujo de datos, pero no parece funcionar igual que el tiempo de espera. ¿Cómo puedo lograr esto? ¿Es esta siquiera la forma correcta de abordar este problema?
Respuesta #1
EDITAR :
this.dataEmitter = of(this.data.row).pipe(delay(1000)).subscribe(row => {
for (let item of row) {
this.dataRow.push(item);
}
}
delay(1000) retrasa 1 segundo por cada emisión. Y tu fragmento no es correcto: no puedes push(row) porque row es undefined (como se ve en el fragmento).
entonces si this.data.row es un Objeto, necesitas hacerlo iterable (como un arreglo) si quieres emitir this.data.row en "pedazos".
Pero si solo quieres deshacerte de setTimeout:
this.dataEmitter = from([this.data.row]).pipe(delay(1000)).subscribe(row => {
for (let item of row) {
this.dataRow.push(item);
}
}
Respuesta #2
Tu código sería así:
this.dataRow = []
of(this.data.row)
.pipe(delay(500))
.subscribe(data => {
for(let item of data) {
this.dataRow.push(item);
}
})
