1

I have a component that gets data from server. My service has a BehaviorSubject<any[]>([]) to get data.

export class AppComponent {
  items: Observable<any[]>;

  constructor(private service: MyService) {
    this.items = service.getItems();
    // this items format is like: `[{id:1,name:'cat'},{id:2,name:'dog'}]`
  }

  addItem(item:any){
   // add item to `this.items` observable array ???
  }

  removeItem(item:any){
   // remove item from `this.items` observable array ???
  }
}

And my service is like following:

@Injectable()
export class MyService{
    private items = new BehaviorSubject<any[]>([]);

    constructor(private http: HttpClient) {
      this.loadItems();
    }

    private loadItems() {
      this.http.get<any[]>('/api/items')
        .subscribe((i) => this.items.next(i));
    }

    getItems() {
      return this.items.asObservable();
    }

    addItem(item: any) {
      return this.http
        .post<any>('/api/items', item)
        .subscribe(() => this.loadItems());
    }
}

I need to add add and remove an item to this observable array but could not do it. The service can add data to server, but I need to add array without send to server. Is this possible?

11
  • 2
    Possible duplicate of Angular 6 add items into Observable Commented Oct 13, 2019 at 14:17
  • It's possibly a duplicate as posted by @jitender. On another note: Please also share the code within MyService. Commented Oct 13, 2019 at 14:19
  • Are you assign array into BehaviourSubject (BehaviorSubject<any[]>([])) that you need the array to be added into another array (items: Observable<any[]>;)? Commented Oct 13, 2019 at 14:25
  • @varman no I did not. Should I add? Can you type solution as answer? Commented Oct 13, 2019 at 14:28
  • So you need to pass only one value to behaviour subject and put into the array, isn't it? Commented Oct 13, 2019 at 14:54

2 Answers 2

4

In your case you don't need to define BehaviourSubject, because you are not maintaining state over the application. So simply you can use like following.

In your service component, write only the service. Because service is a singleton which is only one time initialized.

@Injectable()
export class SomeDataService {    

    //Made this as observable, But when you use httpClient, No need to use Observable.of(), you can directly return like this.http.get<any[]>('/api/items')

    myData=Observable.of([{id:1,name:'cat'},{id:2,name:'dog'},{id:3,name:'rabbit'}])
    constructor() {     
    }

    loadItems() {
      // in your case, return this.http.get<any[]>('/api/items')
      return this.myData;
    }
}

In the AppComponent

export class AppComponent implements OnInit {
    counter=4;
    mydata=[]; //No point to make this as Observable array

    constructor(private _service: SomeDataService) { }

    public ngOnInit(): void {
        this._service.loadItems().subscribe(res=>{     
            this.mydata=res;       
        })  
    }

    addData(){
        let increment=this.counter++
        let data={id:increment,name:increment+"data"}
        this.mydata.push(data)
    }

    removeData(item){
        let index=this.mydata.indexOf(item)
        this.mydata = this.mydata.filter((val,i) => i!=index); 
    }
}

In html,

<button (click)="addData()">Add data</button>

<table>
    <tr>
        <th>Id</th>
        <th>Name</th>
        <th>Action</th>
    </tr>
    <tr *ngFor="let data of mydata;let i=index;">
        <td>{{data.id}}</td>
        <td>{{data.name}}</td>
        <td><button (click)="removeData(data)">Remove data</button></td>
    </tr>
</table>

Click here for the demo Stackblitz.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi Varman. Please do not roll back good edits here, or add chatty/conversational material to posts. Technical writing is preferred. If you are not familiar with the guidelines for succinct writing, please let me know, so I can point you to some relevant posts on Meta.
2

You will need to subscribe to the observables and return the values, before you can do any further manipulation.

For instance,

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})

export class AppComponent implements OnInit {
  items: any[];

  constructor(private service: MyService) {

  }

  ngOnInit() {
    this.service.getItems().subscribe(res => {
      console.log(res);
      this.items = res;
    });
  }

addItem(){
  // this.items.push(someObject)
}


}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.