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 the StaticDataMock
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 with StaticDataMock
.console.log()
to show that component.observableResult$
never emits.As per the comments below, the Stackblitz link above has been updated and is now working. From that Stackblitz here is the working spec:
it('should change return of service.function1() only', () => {
fixture.detectChanges();
component.observableResult$.subscribe(value => {
console.log('observable Emitted, value is ', value);
expect(value[0].id==1).toBe(true);
});
component.myForm.get('localId').setValue(1);
});
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 the subscribe()
.
I am glad this worked!