Soy nuevo en IONIC / Angular y Javascript, pero tengo algo de experiencia en otros idiomas. El problema al que me enfrento es que obtengo datos JSON de una API externa (he creado una API con Strapi) y obtengo las respuestas, pero no puedo mostrarlas en Vistas.

Aqui esta mi codigo ingrese la descripción de la imagen aquí vocales.servicio.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
 
// Typescript custom enum for search types (optional)
export enum SearchType {
  all = '',
  vowels = 'vowel',
  easy = 'easy',
  hard = 'hard',
  naglos = 'naglos',
  wyglos = 'wyglos',
  srodglos = 'srodglos'
}

// Typescript custom enum for search types (optional)
export enum Categories {
  all = '',
  naglos = 'naglos',
  wyglos = 'wyglos',
  srodglos = 'srodglos'
}
 
@Injectable({
  providedIn: 'root'
})
export class VowelService {
  url = 'http://localhost:1337/vowels';
 
  /**
   * Constructor of the Service with Dependency Injection
   * @param http The standard Angular HttpClient to make requests
   */
  constructor(private http: HttpClient) { }
 
  /**
  * Get data from the local API 
  * map the result to return only the results that we need
  * 
  * @param {string} title Search Term
  * @param {string} vowelType
  * @param {Categories} categories easy, hard, 
  * @returns Observable with the search results
  */
  searchData(title: string): Observable<any> {
    return this.http.get(`${this.url}?name=${encodeURI(title)}`).pipe(
      map(results => results['Search'])
    );
  }

  /* GET only Vowels that has category equal to = 
  */

  searchVowel(type: Categories): Observable<any> {
  return this.http.get(`${this.url}?&categories.name=${type}`).pipe(
    map(results => results['Search'])
  );
}
 
  /**
  * Get the detailed information for an ID using the "i" parameter
  * 
  * @param {string} id imdbID to retrieve information
  * @returns Observable with detailed information
  */
  getDetails(id) {
    return this.http.get(`${this.url}?i=${id}&plot=full`);
  }
}

vocales.page.html

<ion-header>
  <ion-toolbar color="primary">
    <ion-title>Wyszukiwarka samogłosek</ion-title>
  </ion-toolbar>
</ion-header>
 
<ion-content>
 
  <ion-searchbar [(ngModel)]="searchTerm" (ionChange)="searchChanged($event)"></ion-searchbar>
 
  <ion-item>
    <ion-label>Wybierz typ</ion-label>
    <ion-select [(ngModel)]="type" (ionChange)="searchChangedVowels($event)">
      <ion-select-option value="">Wszystkie</ion-select-option>
      <ion-select-option value="naglos">Nagłos</ion-select-option>
      <ion-select-option value="srodglos">Śródgłos</ion-select-option>
      <ion-select-option value="wyglos">Wygłos</ion-select-option>
    </ion-select>
  </ion-item>
 
  <ion-list>
 
    <ion-item button *ngFor="let item of (results | async)" [routerLink]="['/', 'vowels', item.id]">

 
      <ion-label text-wrap>
        <h3>{{ item.id }}</h3>
        <h3>{{ item.name }}</h3>
      </ion-label>
 
 
    </ion-item>
 
  </ion-list>
 
</ion-content>

vocales.page.ts

import { VowelService, Categories } from './../../services/vowels.service';
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
 
@Component({
  selector: 'app-vowels',
  templateUrl: './vowels.page.html',
  styleUrls: ['./vowels.page.scss'],
})
export class VowelsPage implements OnInit {
 
  results: Observable<any>;
  searchTerm: string = '';
  type: Categories = Categories.all;
 
  /**
   * Constructor of our first page
   * @param vowelService The movie Service to get data
   */
  constructor(private vowelService: VowelService) { }
 
  ngOnInit() { }
 
  searchChanged() {
    // Call our service function which returns an Observable
    this.results = this.vowelService.searchData(this.searchTerm);
  }

  searchChangedVowels() {
    // Call our service function which returns an Observable
    this.results = this.vowelService.searchVowel(this.type);
    
  }
}
1
johnsmith 23 ene. 2021 a las 12:14

1 respuesta

La mejor respuesta

No obtiene la visualización de los datos en su página ya que el operador del mapa consumió el observable.
Debe usarlo en su archivo de servicio como:

pipe(map(results => {
    return results["search"]
  }))

De esta manera, su función devolverá un Observable.
También debe cambiar el método en sus vocales.page.ts como algo como:

//Results are type of object or any in my example
results: any || yourDataModelType ;  
this.vowelService.searchData(this.searchTerm).subscribe(results => {
    this.results = results;
})

De esta forma has generado un Observable y consumido en tu página cuando obtienes los datos de tu servidor.

Tenga en cuenta que solo obtendrá los resultados cuando el observable devuelva un dato que pueda consumirse.

Otra nota es que cuando se suscribe a un observable, debe cancelar la suscripción cuando haya terminado con él para fines de pérdida de memoria. En Ionic / Angular, puede hacerlo dentro de un ciclo ngOnDestroy (). con algo como:

//Define a subscription variable in your page.ts   
sub: Subscription  

//Assign it inside your function
this sub =  this.vowelService.searchData(this.searchTerm).subscribe(results => {
    this.results = results;  
})
 
//Define OnDestroy Cycle for the page
export class VowelsPage implements OnInit, OnDestroy

//Add ngOnDestroy cycle and unsubscribe inside.
ngOnDestroy(){  
    if(this.sub){sub.unsubscribe()}
}

Le sugiero que eche un vistazo más profundo a la biblioteca de RxJs y compruebe el tipo observable para una mejor comprensión. https://www.learnrxjs.io/

1
Ajan65 23 ene. 2021 a las 10:37