
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@angular-kit/rx-stateful
Advanced tools
Powerful RxJs extensions to level up your streams with stateful operators.
rxStateful$ is a powerful RxJs operator that wraps async Observable and provides a
stateful stream. It does offer out of the box
npm install @angular-kit/rx-stateful
yarn add @angular-kit/rx-stateful
pnpm add @angular-kit/rx-stateful
A live demo is available on here
rxRequest standalone function[!TIP] rxRequest is basically the same as rxStateful$ but with a more ergonomic API. It is recommended to use
rxRequestinstead ofrxStateful$.
import { rxRequest } from '@angular-kit/rx-stateful';
const req = rxRequest({
// optional trigger. If given the requestFn will only be executed if the trigger emits. If not given the requestFn will be executed immediately on subscribe
trigger: trigger$,
// the request function. This can be a function that returns an Observable e.g. vrom an http call
requestFn: () => from(fetch('...')),
config: {...}
})
// get the state stream
/**
* Async Observable will return:
* [
* { value: null, hasValue: false, context: 'suspense', hasError: false, error: undefined },
* { value: SOME_VALUE, hasValue: true, context: 'next', hasError: false, error: undefined },
* ]
*/
const value$ = req.value$();
rxRequest.value$() returns a Observable of with following properties:
value - the valuehasValue - boolean if a value is presentcontext - the context of the stream ('suspense', 'next', 'error', 'complete')hasError - boolean if an error is presenterror - the error, if presentisSuspense - suspense/loading staterxRequest.refresh() offers a convenient way to trigger a refresh of the source. It will trigger the source again and emit the new states.
rxStateful$ standalone functionimport { rxStateful$ } from '@angular-kit/rx-stateful';
/**
* Async Observable will return:
* [
* { value: null, hasValue: false, context: 'suspense', hasError: false, error: undefined },
* { value: SOME_VALUE, hasValue: true, context: 'next', hasError: false, error: undefined },
* ]
*/
const stateful$ = rxStateful$(from(fetch('...')));
const trigger$$ = new Subject<number>()
const refresh$$ = new Subject<void>()
const stateful$ = rxStateful$((id: number) => from(fetch(`.../${id}`)), {
sourceTriggerConfig: {
trigger: trigger$$
},
refetchStrategy: withRefetchOnTrigger(refresh$$)
});
rxStateful$ returns a Observable of with following properties:
value - the valuehasValue - boolean if a value is presentcontext - the context of the stream ('suspense', 'next', 'error', 'complete')hasError - boolean if an error is presenterror - the error, if presentisSuspense - suspense/loading staterxStateful$ or rxRequestBoth rxRequest and rxStateful$ provides configuration possibility on instance level or globally.
You can provide a global configuration for rxStateful$ and rxRequest. This configuration will be used for every instance of rxStateful$ and rxRequest.
Use provideRxStatefulConfig in either your AppModule or appConfig to provide a global configuration.
You can also provide a configuration on instance level. This will also override the global configuration (if present).
keepValueOnRefresh - boolean if the value should be kept when the refreshTrigger$ emits. Default: falsekeepErrorOnRefresh - boolean if thel last error should be kept when the refreshTrigger$ emits. Default: falserefreshTrigger$ - a Subject or Observable that triggers the source again. Default: not set. deprecated use refetchStrategiesrefetchStrategies - single or multiple RefetchStrategies to trigger the source again. Default: not setsuspenseThresholdMs - number of milliseconds to wait before emitting the suspense state. Default: 0suspenseTimeMs - number of milliseconds to wait before the next state after the suspense state. Default: 0[!TIP] A few more words about the
suspenseThresholdMsandsuspenseTimeMsconfiguration. This is a quite powerful feature which will result in a better UX when preventing flickering loading states. What does flickering loading states mean? When you show a loading indicator/spinner based on theisSuspense-property then a common scenario is that you show a spinner for a very short tim for fast requests resulting in some flickering. To prevent this it is better to wait a certain amount of time before showing a spinner (suspenseThreshold). If then the request takes longer thant the threshold-time a spinner will be shown for at least another amount of time (suspenseTime). That way you can prevent flickering spinners.
rxStateful$provides exactly this feature and will only emit the suspense-state if a async-operation takes longer than the specifiedsuspenseThresholdMsfor at leastsuspenseTimeMs. A reasonable configuration of these two values would be to set them both to 500ms.
[!IMPORTANT] The default value for
suspenseThresholdMsandsuspenseTimeMsis 0, therefor by default you will not use the non-flickering loading state feature. It is choosen that way to break existing behavior. This might change in a future major version.
import { rxStateful$, rxRequest } from '@angular-kit/rx-stateful';
const rxStateful$ = rxStateful$(someSource$, { keepValueOnRefresh: true });
const rxRequest = rxRequest({ requestFn: () => someSource$, config: { keepValueOnRefresh: true } });
refetchStrategieswithRefetchOnTriggerwithAutoRefetchRxStatefulClient[!CAUTION] The
RxStatefulClientis a experimental feature. Breaking changes might occur in any version update.
In order to use RxStatefulClient you first need to provide it, e.g. in your AppModule:
import {provideRxStatefulClient} from "@angular-kit/rx-stateful";
@NgModule({
providers: [
provideRxStatefulClient()
],
})
export class AppModule {}
RxStatefulClient offers a request-method which basically has the same signature as rxStateful$ - so there'is no
difference in usage.
provideRxStatefulClient() can be configured:
import {provideRxStatefulClient, withConfig} from "@angular-kit/rx-stateful";
@NgModule({
providers: [
provideRxStatefulClient(withConfig({ keepValueOnRefresh: true}))
],
})
export class AppModule {}
The global configuration will be used for every request-call. You can still override the global configuration by
providing a configuration object as second parameter to request-method.
Both rxStateful$ and RxStatefulClient can be configured to refresh the source (e.g. make a HTTP call again).
To define the refresh behaviour you can make use of so called RefetchStrategy's. Right now there are following strategies
built in: withAutoRefetch and withRefetchOnTrigger.
rxStateful$```typescript
const instance = rxStateful$(fetch(), { refetchStrategy: [withAutoRefetch(1000, Infinity)] })
RxStatefulClient
const client = inject(RxStatefulClient);
const instance = client.request(fetch(), { refetchStrategy: [withAutoRefetch(1000, Infinity)] })
All strategies can be cominded in an arbitrary way.
In the future there will come more strategies built in, as well as an easy way to define custom strategies. However defining
custom strategies is already possible by implementing the RefetchStrategy interface.
Please have a look at the testing documentation.
This project follows Semantic Versioning.
2.x.x requires Angular >=18.0.01.x.x requires Angular >=14.0.0MIT
Any Contributions are welcome. Please open up an issue or create PR if you would like to contribute.
See CONTRIBUTING.md for more information.
FAQs
Powerful RxJs extensions to level up your streams with stateful operators.
We found that @angular-kit/rx-stateful demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.