0

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,
    });
  }
}
14
  • Please add the code where the assignment happens including the declaration of the field you assign it to Commented Dec 5, 2022 at 12:07
  • Are you subscribing to your getGameList$ somewhere in your app? Commented Dec 5, 2022 at 12:17
  • @MoxxiManagarm, I added two files Commented Dec 5, 2022 at 12:17
  • I mean the code, that calls getGameList$ Commented Dec 5, 2022 at 12:19
  • @Mehyar Sawas I will subscribe in the app.component inside ngOnInit() Commented Dec 5, 2022 at 12:20

2 Answers 2

1

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,
    });
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

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,
    });
  }
}

5 Comments

What did you change and why? A good answer should explain mistakes and solutions and not just provide code to copy-paste.
I'm type casting the Observable to GameInfo[] which is returned from Http.get method, as getGameList$ requires that type.
Then you should add this to the question. But that's exactly the same as in the original piece of code in the question. And it's not casting, you are calling a template method. Also this is a custom service, not angular's HttpClient.
You are right, But we don't know about his httpService. I added comment to main question about his HttpClient's get method.
What about the other type of responses from the server? A get request should have a generic type. In your solution you are considering all the responses coming from any api as GameInfo[]

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.