Home > Mobile >  How can I assign an Observable<Array[]> for function result that returns array of objects?
How can I assign an Observable<Array[]> for function result that returns array of objects?

Time:12-06

I have a function in a service that retrieves an array of objects with configurations. I'm trying to assign the return type to this method as Observable<GameInfo[]> but I'm getting the error:

Type 'Observable<object>' is not assignable to type 'Observable<GameInfo[]>'.
   Type '{}' is missing the following properties from type 'GameInfo[]': length, pop, push, concat, and 29 more.

I created interface for data validation that looks like this:

export default interface GameInfo {
  type: string;
  prizes: any;
  nameLocalKey: string;
  ticketPrice: number;
}

and tried to apply it, but it was unsuccessful.

It's my function that should return the Observable array:

  getGameList$(): Observable<GameInfo[]> {
    return this.httpService.get<GameInfo[]>(BackendRoutes.GameList);
  }

Data format:

[
    {
        "type": "BINGO_75",
        "prizes": [
            {
                "name": "Prize 1",
                "nameLocaleKey": "PRIZES.BINGO_75.PRIZE_1",
                "winAmount": 10,
                "patterns": [
                    {
                        "type": "HORIZONTAL",
                        "count": 1
                    },
                    {
                        "type": "VERTICAL",
                        "count": 1
                    },
                    {
                        "type": "DIAGONAL",
                        "count": 1
                    }
                ]
            },
            {
                "name": "Prize 2",
                "nameLocaleKey": "PRIZES.BINGO_75.PRIZE_2",
                "winAmount": 10,
                "patterns": [
                    {
                        "type": "HORIZONTAL",
                        "count": 2
                    },
                    {
                        "type": "VERTICAL",
                        "count": 2
                    },
                    {
                        "type": "DIAGONAL",
                        "count": 2
                    }
                ]
            },
            {
                "name": "Prize 3",
                "nameLocaleKey": "PRIZES.BINGO_75.PRIZE_3",
                "winAmount": 10,
                "patterns": [
                    {
                        "type": "HORIZONTAL",
                        "count": 3
                    },
                    {
                        "type": "VERTICAL",
                        "count": 3
                    }
                ]
            },
            {
                "name": "Prize 4",
                "nameLocaleKey": "PRIZES.BINGO_75.PRIZE_4",
                "winAmount": 10,
                "patterns": [
                    {
                        "type": "HORIZONTAL",
                        "count": 4
                    },
                    {
                        "type": "VERTICAL",
                        "count": 4
                    }
                ]
            },
            {
                "name": "Full house",
                "nameLocaleKey": "PRIZES.BINGO_75.PRIZE_5",
                "winAmount": 10,
                "patterns": [
                    {
                        "type": "HORIZONTAL",
                        "count": 5
                    }
                ]
            }
        ],
        "nameLocaleKey": "GAMES.BINGO_75",
        "ticketPrice": 10
    }
]

EDITED

Here the code that send the data from server and we process this response inside function getGameList$()

const express = require("express");
const router = express.Router();
const gameList = require("../config/bingo");

router.get("/list", (req, res) => {
  const keys = Object.keys(gameList);

  const listOfGameConfigurations = keys.map((key) => {
    const currentGameConfiguration = gameList[key];

    const {
      type,
      prizes,
      nameLocaleKey,
      tickets: { price: ticketPrice },
    } = currentGameConfiguration;

    const newObject = { type, prizes, nameLocaleKey, ticketPrice };
    console.log(newObject);

    return newObject;
  });
  return res.json(listOfGameConfigurations);
});

module.exports = router;

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import BackendRoutes from 'src/app/core/enums/backend-routes';
import { HttpService } from 'src/app/core/services/http.service';
import GameInfo from '../interfaces/game-info';

@Injectable({
  providedIn: 'root',
})
export class GameService {
  constructor(private httpService: HttpService) {}

  getGameList$(): Observable<GameInfo[]> {
    return this.httpService.get(BackendRoutes.GameList);
  }
}

EDITED 2

Added httpService code:

export class HttpService {
  private httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    withCredentials: true,
  };
  private domain = environment.domain;

  constructor(private http: HttpClient) {}

  post(
    route: string,
    body: object,
    httpOptions: object = this.httpOptions
  ): Observable<object> {
    return this.http.post(`${this.domain}${route}`, body, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }

  get(
    route: string,
    httpOptions: object = this.httpOptions
  ): Observable<object> {
    return this.http.get(`${this.domain}${route}`, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }
}

CodePudding user response:

Thank you all for your help. The error was that I had a specific return type set. Generics helped.

export class HttpService {
  private httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    withCredentials: true,
  };
  private domain = environment.domain;

  constructor(private http: HttpClient) {}

  post<T>(
    route: string,
    body: object,
    httpOptions: object = this.httpOptions
  ): Observable<T> {
    return this.http.post<T>(`${this.domain}${route}`, body, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }

  get<T>(route: string, httpOptions: object = this.httpOptions): Observable<T> {
    return this.http.get<T>(`${this.domain}${route}`, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }
}

CodePudding user response:

Make changes to your HttpService. It should return Observable<GameInfo[]> because your function getGameList$() is expecting Observable<GameInfo[]>.

export class HttpService {
  private httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
    withCredentials: true,
  };
  private domain = environment.domain;

  constructor(private http: HttpClient) {}

  post(
    route: string,
    body: object,
    httpOptions: object = this.httpOptions
  ): Observable<object> {
    return this.http.post(`${this.domain}${route}`, body, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }

  get(
    route: string,
    httpOptions: object = this.httpOptions
  ): Observable<GameInfo[]> {
    return this.http.get(`${this.domain}${route}`, {
      ...this.httpOptions,
      ...httpOptions,
    });
  }
}
  • Related