mycomponent.ts
import { Component, OnInit } from '@angular/core';
import {FormGroup,FormControl} from '@angular/forms'
import { DataServiceService } from './data-service.service';
import {combineLatest,Observable,pipe} from 'rxjs';
import {map,tap} from 'rxjs/operators';
import {Model} from './mode';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
constructor(private dataService: DataServiceService){}
name = 'Angular';
myForm: FormGroup;
observableResult$: Observable<any>;
ngOnInit(){
this.myForm = new FormGroup({
localId: new FormControl()
})
this.observableResult$ = combineLatest(
this.myForm.get('localId').valueChanges,
this.dataService.getDataFromURL(),
(localIdSelected, dataFromAPI) => ({localIdSelected,dataFromAPI})).
pipe(map(each => this.filterData(each.dataFromAPI,each.localIdSelected)));
this.observableResult$.subscribe(value => {
debugger
})
}
filterData(dataFromAPI,localIDSelected){
debugger
return dataFromAPI.filter(item => item.userId > Number(localIDSelected));
}
}
data.service.service.ts
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'
import {Model} from './mode';
import {Observable} from 'rxjs';
@Injectable()
export class DataServiceService {
constructor(private http:HttpClient) { }
getDataFromURL():Observable<Model>{
return this.http.get<Model>('https://jsonplaceholder.typicode.com/todos');
}
}
app.component.html
<form [formGroup]="myForm" >
<select formControlName="localId">
<option>1</option>
<option>2</option>
</select>
</form>
app.spec.ts
const spyFilter = spyOn(component as any, filterData).and.callThrough();
const constAPIData$ = staticDataServiceMock.getAPIData();
spyOn(staticDataServiceMock, 'getAPIData').and.returnValue(
observableOf(countryStaticData$)
);
component.myForm.get('localId').setValue(1);
component.observableResult$.subscribe(value => {
expect(value[0].id==21).toBeTrue();
});
staticDatamock.ts
export class StaticDataMock{
static getAPIData(): Observable<StaticDataElements[]> {
return [
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
{
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
},
{
"userId": 1,
"id": 4,
"title": "et porro tempora",
"completed": true
}];
}
}
I have added my test case to cover the combineLatest operator anf filterData in app.spec.ts, but the required code fails. and my expectation to call filterData is failed. combineLatest will fire the event on a valueChange and get data from API. i can created mock and setValue inside spec file, still it is not working.
Ok, to try and help you get going on this, I went ahead and set up a Stackblitz with the data you have provided so far. Here is the link.
I did a few things to get the test working (sort of).
getAPIData()
within theStaticDataMock
class to public so you could call it from outside the class.of()
, turning the return value into an Observable of your data.getDataFromURL()
in the service and return the observable you had created withStaticDataMock
.console.log()
to show thatcomponent.observableResult$
never emits.Update
As per the comments below, the Stackblitz link above has been updated and is now working. From that Stackblitz here is the working spec:
The key to this was to set up the subscribe first, and then emit a new value in the form, which will update the the
combineLatest()
and execute the code inside thesubscribe()
.I am glad this worked!