2

Using Angular 7 I had this:

export class Envelope<T> {
  result: T[];

  constructor(result: T[]) {
    this.result = result;
  }
}

I mapped Observable<Envelope<Todo>>, return by todoService, to Observable<TodoModel[]>:

let models: Observable<TodoModel[]> = this.todoService.get()
  .pipe(
    map((envelope: Envelope<Todo>) => 
      envelope.result.map((todo: Todo) => { 
        return {
          content: todo.content
          // Other properties
        };
      })));

This is working but now Envelope changed to (result: T and not result: T[]):

export class Envelope<T> {
  result: T;

  constructor(result: T) {
    this.result = result;
  }
}

I need to map Observable<Envelope<Todo[]>> to the same Observable<TodoModel[]>:

let models: Observable<TodoModel[]> = this.todoService.get()
  .pipe(
    map((envelope: Envelope<Todo[]>) => 
      envelope.result.map((todo: Todo) => { 
        return {
          content: todo.content
          // Other properties
        };
      })));

I tried a few options but I get the following error:

Argument of type 'OperatorFunction<Envelope<Todo[]>, { content: string; }[]>' 
is not assignable to parameter of type 'OperatorFunction<Envelope<Todo>, { content: string; }[]>'.

Type 'Envelope<Todo[]>' is not assignable to type 'Envelope<Todo>'.
Type 'Todo[]' is missing the following properties from type 'Response': content.

Could someone, please, let me know how to do the mapping?

Update

The API returns, for example, something as follows:

{
  "result": [
    { "id": 1, "title": "T1", content: "C1" },
    { "id": 2, "title": "T2", content: "C2" }
  ]
} 

Then the TodoService returns it as an Observable<Envelope<Todo[]>> where Todo is:

interface Todo {
  id: number;
  title: string;
  content: string;
}

In the component I need to map Observable<Envelope<Todo[]>> to Observable<TodoModel[]> where TodoModel is:

interface TodoModel {
  title: string;
  content: string;
}

I have more complex scenarios in my application but the base is this.

4
  • envelope.result.map maps an Object and returns a mapped Object. It will never return Array. And if you change type from envelope: Envelope<Todo> to envelope: Envelope<Todo[]>, it will not impact output in any way. It is not a run time code. Commented May 13, 2019 at 19:30
  • Sorry, I didn't quite understand your answer ... Could you, please, post a code sample? Commented May 13, 2019 at 19:33
  • It would be best if you show what data you get and what data shape you want it to turn in Commented May 13, 2019 at 19:45
  • I added an update ... Does it help? Commented May 13, 2019 at 21:28

1 Answer 1

2

Do you need to observe the envelope? Maybe something like this would more straight forward. If the envelope contains a list of todos

result: Observable<TodoModel>; 

    this.todoService.get()
          .subscribe((envelope: any) => {
            this.result = envelope.todo.content;       
          });
Sign up to request clarification or add additional context in comments.

1 Comment

Envelope has other information like Paging which is related with result itself ... Shouldn't I include it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.