admin管理员组文章数量:1123692
I have a component with 2 input signals that have no value initially. I need to send http request only one time and it should be the moment both signals have value.
What is the proper way to do it? Should I use effect that I manually destroy after first execution or is there some other way?
I have a component with 2 input signals that have no value initially. I need to send http request only one time and it should be the moment both signals have value.
What is the proper way to do it? Should I use effect that I manually destroy after first execution or is there some other way?
Share Improve this question asked yesterday tlttlt 15.1k11 gold badges51 silver badges91 bronze badges3 Answers
Reset to default 1Really it's the reason to use signals and effect. Just check if have value the two inputs:
export class MyComponent {
value1 = input<any>(null);
value2 = input<any>(null);
constructor() {
effect(() => {
const value1=this.value1()
const value2=this.value2()
if (value1 && value2)
..do something..
});
}
}
A stackblitz
This is my version, which uses rxResource
to cache the value once a certain condition is met, we can use cached
property to store the cached value and return it, when it is being set (the condition that sets this property is when both the signals have a value).
First we initialize a rxResource
to make the API call, we use two signals (signal1
and signal2
) (I am using modal instead of input here), Using this, we can make the API setup.
Then we can use a simple if condition to cache the value when our condition is met.
cached!: any[];
resource: ResourceRef<any[]> = rxResource({
request: () => ({
signal1: this.signal1(),
signal2: this.signal2(),
}),
loader: ({ request: { signal1, signal2 } }) => {
if (this.cached) {
return of(this.cached);
}
if (signal1 && signal2) {
// simulate API
return of([{ dataReceved: true }]).pipe(
tap((res: any) => {
this.cached = res;
})
);
}
return EMPTY;
},
});
Full Code:
import {
Component,
effect,
linkedSignal,
model,
ResourceRef,
ResourceStatus,
WritableSignal,
} from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { rxResource } from '@angular/core/rxjs-interop';
import { of, EMPTY, tap } from 'rxjs';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
imports: [CommonModule, FormsModule],
template: `
{{ resource.value() | json }}
<input [(ngModel)]="signal1" />
<input [(ngModel)]="signal2" />
`,
})
export class App {
signal1 = model(null);
signal2 = model(null);
cached!: any[];
resource: ResourceRef<any[]> = rxResource({
request: () => ({
signal1: this.signal1(),
signal2: this.signal2(),
}),
loader: ({ request: { signal1, signal2 } }) => {
if (this.cached) {
return of(this.cached);
}
if (signal1 && signal2) {
// simulate API
return of([{ dataReceved: true }]).pipe(
tap((res: any) => {
this.cached = res;
})
);
}
return EMPTY;
},
});
}
bootstrapApplication(App);
Stackblitz Demo
To trigger an HTTP request when both input signals have values in Angular, you can use the combineLatest
operator from RxJS. This approach ensures the request is sent only once, as soon as both signals are non-null, and it automatically unsubscribes after the first emission.
Example Code:
Below is a complete implementation of the solution:
import { Component, Input, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Signal } from '@angular/core';
import { combineLatest, filter, take } from 'rxjs';
@Component({
selector: 'app-my-component',
template: `<!-- Your template here -->`,
})
export class MyComponent implements OnInit {
@Input() signal1!: Signal<any>;
@Input() signal2!: Signal<any>;
constructor(private http: HttpClient) {}
ngOnInit() {
combineLatest([this.signal1, this.signal2])
.pipe(
filter(([value1, value2]) => value1 != null && value2 != null), // Ensure both have values
take(1) // Automatically unsubscribe after the first emission
)
.subscribe(([value1, value2]) => {
// Send your HTTP request here
this.http.post('https://example.com/api', { value1, value2 }).subscribe(
response => {
console.log('HTTP request successful:', response);
},
error => {
console.error('HTTP request failed:', error);
}
);
});
}
}
本文标签: angularHow to run function just one time when 2 signals have valueStack Overflow
版权声明:本文标题:angular - How to run function just one time when 2 signals have value? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736587276a1945028.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论