I’m trying to integrate @ngneat/query
with signals in my Angular application. However, I’m encountering the following error:
<code>Error: NG0203: queryResultSignal() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. More details can be found at https://angular.dev/errors/NG0203
</code>
<code>Error: NG0203: queryResultSignal() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. More details can be found at https://angular.dev/errors/NG0203
</code>
Error: NG0203: queryResultSignal() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`. More details can be found at https://angular.dev/errors/NG0203
In my code example, I’m attempting to load a product based on a parameter from the route. To achieve this, I convert the product parameter into a signal using:
<code>productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
</code>
<code>productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
</code>
productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
Then, inside the computed function, I call @ngneat/query
with that signal.
However, it’s not working as expected. What am I missing in my code to make it function correctly?
You can find a StackBlitz demo of my code here.
<code>import { CommonModule } from '@angular/common';
import { Component, computed, inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { ActivatedRoute, RouterModule, provideRouter } from '@angular/router';
import { injectQuery } from '@ngneat/query';
import { delay, map, of } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
import 'zone.js';
console.clear();
@Component({
standalone: true,
selector: 'product',
imports: [CommonModule],
template: `
in product:
<ng-container *ngIf="product() as product">
{{product.data |json}}
</ng-container>
`,
})
export class ProductComponent {
query = injectQuery();
productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
product = computed(() => this.getProduct(this.productId()!).result());
getProduct(id: number) {
return this.query({
queryKey: ['product', id],
queryFn: () => of({ id }).pipe(delay(2 * 1000)), // <-- replace http call here
});
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule],
template: `
<h1>Hello from {{ name }}!</h1>
<a [routerLink]="['/1']">goto product 1</a>
<hr>
<router-outlet></router-outlet>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App, {
providers: [provideRouter([{ path: ':id', component: ProductComponent }])],
});
</code>
<code>import { CommonModule } from '@angular/common';
import { Component, computed, inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { ActivatedRoute, RouterModule, provideRouter } from '@angular/router';
import { injectQuery } from '@ngneat/query';
import { delay, map, of } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
import 'zone.js';
console.clear();
@Component({
standalone: true,
selector: 'product',
imports: [CommonModule],
template: `
in product:
<ng-container *ngIf="product() as product">
{{product.data |json}}
</ng-container>
`,
})
export class ProductComponent {
query = injectQuery();
productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
product = computed(() => this.getProduct(this.productId()!).result());
getProduct(id: number) {
return this.query({
queryKey: ['product', id],
queryFn: () => of({ id }).pipe(delay(2 * 1000)), // <-- replace http call here
});
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule],
template: `
<h1>Hello from {{ name }}!</h1>
<a [routerLink]="['/1']">goto product 1</a>
<hr>
<router-outlet></router-outlet>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App, {
providers: [provideRouter([{ path: ':id', component: ProductComponent }])],
});
</code>
import { CommonModule } from '@angular/common';
import { Component, computed, inject } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { ActivatedRoute, RouterModule, provideRouter } from '@angular/router';
import { injectQuery } from '@ngneat/query';
import { delay, map, of } from 'rxjs';
import { toSignal } from '@angular/core/rxjs-interop';
import 'zone.js';
console.clear();
@Component({
standalone: true,
selector: 'product',
imports: [CommonModule],
template: `
in product:
<ng-container *ngIf="product() as product">
{{product.data |json}}
</ng-container>
`,
})
export class ProductComponent {
query = injectQuery();
productId = toSignal(
inject(ActivatedRoute).params.pipe(map((params) => Number(params['id'])))
);
product = computed(() => this.getProduct(this.productId()!).result());
getProduct(id: number) {
return this.query({
queryKey: ['product', id],
queryFn: () => of({ id }).pipe(delay(2 * 1000)), // <-- replace http call here
});
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterModule],
template: `
<h1>Hello from {{ name }}!</h1>
<a [routerLink]="['/1']">goto product 1</a>
<hr>
<router-outlet></router-outlet>
`,
})
export class App {
name = 'Angular';
}
bootstrapApplication(App, {
providers: [provideRouter([{ path: ':id', component: ProductComponent }])],
});