我有一个设置,我可以在 firebase 中查询用户最喜欢的帖子列表。
基本上,首先我查询用户喜欢,然后为每个喜欢获取相应的帖子 - 所有这些都在一个可观察的序列中。
当用户不喜欢唯一留下的帖子时,就会出现问题。在这种情况下(当 likes 数组变空时)不会从 observable 中触发任何内容并且视图不会更新(总是至少有一个帖子存在)。
一方面,这种行为似乎合乎逻辑且可以理解,但另一方面,即使 switchMap 的输入为空,我也不知道如何使最终的 Observable 发出。也许应该改变运营商。
getUserFavourites(userId = ""):Observable<Post[]>
{
if (!this.userFavourites$) {
this.userFavourites$ = this.af.database.list('/ranks_by_user/' + userId, {
query: {
limitToFirst: 50
}
}) //Emits value here (even empty array)
.switchMap((likes: any[]) => Observable.combineLatest(
likes.map(like => this.af.database.object("/posts/" + like.$key).first())
)) //Does not emit new value here if likes array was empty
.map(p => {
return p.map(cit => Post.unpack(p));
}).publishReplay(1).refCount()
}
return this.userFavourites$;
}
Run Code Online (Sandbox Code Playgroud) 在我的 Angular2 应用程序中,我从 REST API 获取响应并操作它们以便在用户界面中显示它们。
我根据以下教程编写了我的应用程序。
这是我从服务器获取响应的方法
getTendersByCategory(categoryName: string){
console.log("get tenders by category "+categoryName);
let tendersByCategory = this._http
.get(this._endpointUrl + "tender/get-by-category-name/" + categoryName)
.map(mapTenders)
.catch(handleError);
return tendersByCategory;
}
Run Code Online (Sandbox Code Playgroud)
以下函数用于操作响应
function mapTenders(response: Response): Tender[] {
console.log('tender.service.ts -> mapTenders');
/*if(response.status == 204){
console.log("response = 204 - No content in response");
return null;
}*/
return response.json().map(toTender);
}
function toTender(r: any): Tender {
console.log('tender.service.ts -> toTender');
let tender = <Tender>({
id: r.id,
name: r.name,
publisher: r.publisher,
});
return tender;
}
function handleError(error: …Run Code Online (Sandbox Code Playgroud) angular2-services angular2-http angular2-observables angular
我正在开发一个 Angular (4.1.2) Web 应用程序以及相应的 ASP.Net Core (1.1) Web API。
我有一个 Angular 服务,它向我的 Web API 发出数据 http 请求,并且从 Angular 服务返回的对象中的日期不是类型Date。
Tasks在我的场景中,我的 Web 应用程序从 SQL 数据库获取数据,每个应用程序都Task包含 start 和 finish DateTime。我的 TasksController 使用 AutoMapper 将每个任务映射Task到一个TaskViewModel对象,并且我的 TasksControllerTaskViewModel有一个类型为 的 start 和 finish 属性DateTime。
如果我在 TasksController 中放置一个断点并检查TaskViewModel要返回的对象,那么在请求之后,开始和结束属性都是类型DateTime,因此日、月、小时等都可以。
在 Angular 中,我有一个task-api.service.ts包含以下代码的文件:
public getTasks(): Observable<Task[]> {
let tasksArray: Observable<Task[]> = this.http.get("/api/tasks").map((response: Response) => {
return <Task[]>response.json();
}).catch(this.handleError); …Run Code Online (Sandbox Code Playgroud) 我正在使用材料表原理图,但不知道如何
我认为重要的部分是文件connect()中的方法datasource.ts。this.data只是一个数组。
/**
* Connect this data source to the table. The table will only update when
* the returned stream emits new items.
* @returns A stream of the items to be rendered.
*/
connect(): Observable<any[]> {
// Combine everything that affects the rendered data into one update
// stream for the data-table to consume.
const dataMutations = [
observableOf(this.data),
this.paginator.page,
this.sort.sortChange
];
// Set the paginators length
this.paginator.length = this.data.length; …Run Code Online (Sandbox Code Playgroud) observable angular-material angular-material2 angular2-observables angular
我有一个 HTTP 服务,它使用 HttpClient 进行 API 调用:
//provider.service.ts
export interface Lesson {
id?: number,
name: string,
type: LessonType,
teacher_data: string,
student_data: string
}
export class ProviderService {
constructor(private http: HttpClient) {}
postLesson(form): Observable<Lesson> {
const body = this.getFormUrlEncoded(form.value);
return this.http.post<Lesson>('/api/lesson/', body, this.postHttpOptions);
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个使用此 ProviderService 的组件,如下所示:
onSubmit():void {
this.providerService.createLesson(lessonForm).subscribe(result=> {
console.log(result);
//do my stuff
});
}
}
Run Code Online (Sandbox Code Playgroud)
它工作得很好,一切都很好。现在我想做一个LessonService,让所有http 调用都通过该服务。它将缓存结果、发出更改等。
我是这样写的:
//updated lessons.component.ts
onSubmit():void {
this.LessonsService.createLesson(this.lessonForm).subscribe(result=> {
console.log(result);
//do my stuff
});
}
//lessons.service.ts
export class LessonsService {
constructor(private http: …Run Code Online (Sandbox Code Playgroud) 在我的项目中,我使用BehaviorSubjects 作为数据存储来存储应用程序的状态。
我只需要存储中当前保存的当前BehaviorSubject值,不需要订阅可以通过行为主体发出的未来值。
我发现很少有实现此操作的方法:使用pipe(take(1)),firstValueFrom和.value。
所有的工作方式都相同并读取BehaviorSubject 存储中的当前值吗?如果有的话,它们之间有什么区别?
private myStore$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
// reading only one current value using take(1):
this.myStore$.pipe(take(1))
.subscribe(value => console.log('current value = ', value));
// reading only one current value using firstValueFrom:
const value = await firstValueFrom(this.myStore$);
console.log('current value = ', value);
// reading only one current value using this.myStore$.value:
const value = this.myStore$.value;
console.log('current value = ', value);
Run Code Online (Sandbox Code Playgroud) 我正在为angular2组件编写测试用例.
我创建了一个使用observable流的服务,如下所示:
import {Injectable} from '@angular/core'
import {Subject} from 'rxjs/Subject';
import {User} from './user.model';
@Injectable()
export class UserService {
selectedUserInstance:User = new User();
// Observable selectedUser source
private selectedUserSource = new Subject<User>();
// Observable selectColumn stream
selectedUser$ = this.selectedUserSource.asObservable();
// service command
selectUser(user:User) {
this.selectedUserInstance=user;
this.selectedUserSource.next(user);
}
}
Run Code Online (Sandbox Code Playgroud)
现在在我的组件中,我订阅了这个流:
getSelectedUser() {
this.subscriptionUser = this.userService.selectedUser$.subscribe(
selectedUser => {
this.selectedUser = selectedUser;
}
);
}
Run Code Online (Sandbox Code Playgroud)
现在在我的spec.ts文件中,我想将此流模拟为:
spyOn(userService, 'selectedUser$')
.and.returnValue(Observable.of({
'name': 'bhushan',
'desc': 'student'
}));
Run Code Online (Sandbox Code Playgroud)
但它一直给我以下错误:
错误:spyOn找不到要监视selectColumn $()的对象
有没有办法做到这一点?
我很长时间以来一直坚持这个问题.
任何输入?
谢谢
当一个可观察的对象运行时,它依赖于来自另一个可观察对象的数据,我无法弄清楚如何正确处理这种依赖关系。
一个可观察的对象从Firebase获取数据,并通过订阅它创建了一个简单的数字数组,称为NovelsRead:数组
另一个可观察到的对象从api获得响应,并且订阅它的目的是过滤出所有小说中存在id的记录。
问题是,当响应来自api时,NovelsRead []仍为空,因为Firebase尚未响应,因此从api响应中将不会过滤任何内容。
代码如下:
导出类首页{
currentnovels: any;
novels: any;
unreadnovels: any;
nextnovels: any;
novel: any;
resultsPageNumber: number = 1;
novelFullPosterPath: any;
novelsread: Array<number> = [];
private basePosterUrlMedium = 'http://image.novels.org/t/p/w500';
private basePosterUrlSmall = 'http://image.novels.org/t/p/w185';
constructor(private http: Http,
private novelsApi: NovelsApiService,
private dataService: DataService,
) {
//this takes data from Firebase and pushes it to simple array of ids (numbers)
this.dataService.list('novels-read')
.subscribe(data => {
data.map(results => {
this.novelsread.push(results.novelsId);
})
})
}
ngAfterViewInit() {
this.novelsApi.getnovelsByPage(this.resultsPageNumber)
.subscribe(data => {
this.novels = data.results; …Run Code Online (Sandbox Code Playgroud) 我们要做的是从URL调用一个端点,该URL返回2个变量,这些变量可以在站点的多个部分中使用。尽管我们正在使用http调用并订阅它,但是为了加快站点速度,我们只想进行一次api调用。为此,我们在服务上创建了一个Observable。服务会在构造函数中调用一个函数,该函数设置Observable的值,但是有时在直接访问链接时会返回无法预订的undefined方法。下面是使用Microsoft ADAL库的示例代码:
首先,我们在服务中将变量设置为Observable:
@Injectable()
export class MicrosoftGraphService {
public details: Observable<any>;
Run Code Online (Sandbox Code Playgroud)
然后我们在构造函数中设置可观察值:
constructor(
private _http:Http,
private _adalService: AdalService,
private _sanitizer:DomSanitizer
) {
this.getToken().subscribe(token => {
/**
* Get me data from graph to determine school_id and mis_id
*/
this.get('me', token, true).subscribe(me => {
this.details = new Observable(observer => {
observer.next({
me: me
});
observer.complete();
});
});
});
Run Code Online (Sandbox Code Playgroud)
getToken函数为:
getToken(): Observable<any> {
return this._adalService
.acquireToken( this._adalService.config.endpoints.graph );
}
Run Code Online (Sandbox Code Playgroud)
get函数是:
get( endpoint, token, beta = false ): Observable<any> {
return this._http.get( this._adalService.config.endpoints.graph …Run Code Online (Sandbox Code Playgroud) 我有一个对象数组,我需要将每个对象分别传递给异步方法(后面的进程用Promise处理,然后通过Observable.fromPromise(...)- 转换回Observable - 需要这种方式,因为只使用单个对象时使用相同的方法随时;进程将对象保存到数据库中).例如,这是一个对象数组:
[
{
"name": "John",
...
},
{
"name": "Anna",
...
},
{
"name": "Joe",,
...
},
{
"name": "Alexandra",
...
},
...
]
Run Code Online (Sandbox Code Playgroud)
现在我有一个名为insert的方法which,它将对象插入到数据库中.store数据库实例的方法返回新创建的id.最后,复制初始对象并使用其新ID进行映射:
insert(user: User): Observable<User> {
return Observable.fromPromise(this.database.store(user)).map(
id => {
let storedUser = Object.assign({}, user);
storedUser.id = id;
return storedUser;
}
);
}
Run Code Online (Sandbox Code Playgroud)
这适用于我插入单个对象的情况.但是,我想添加对插入多个对象的支持,这些对象只调用单个插入的方法.目前这就是我所拥有的,但它不起作用:
insertAll(users: User[]): Observable<User[]> {
return Observable.forkJoin(
users.map(user => this.insert(user))
);
}
Run Code Online (Sandbox Code Playgroud)
该insertAll方法是按预期插入用户(或其他东西填充数据库的用户),但我没有得到任何回复.我正在调试正在发生的事情,似乎forkJoin只是从第一个映射用户获得响应,但其他人被忽略.订阅insertAll不做任何事情,也没有任何错误通过catch insertAll或通过订阅中的第二个参数insertAll.
所以我正在寻找一种解决方案,其中Observable(in …
angular ×9
rxjs ×4
observable ×3
angularfire2 ×1
datetime ×1
firebase ×1
fork-join ×1
jasmine ×1
javascript ×1
rxjs5 ×1