Angular Integration
@opra/angular replaces @opra/client's default FetchBackend with Angular's HttpClient. This means Angular's own interceptor chain, HttpContext, and dependency injection system all remain active — OPRA requests pass through the same pipeline as any other Angular HTTP call.
npm install @opra/client @opra/angular
Setup
Register the client in your module using OpraClientModule.registerClient(). Define an InjectionToken so the client can be injected anywhere in your application.
// api-client.token.ts
import { InjectionToken } from '@angular/core';
import { OpraAngularClient } from '@opra/angular';
export const API_CLIENT = new InjectionToken<OpraAngularClient>('API_CLIENT');
// app.module.ts
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { OpraClientModule } from '@opra/angular';
import { API_CLIENT } from './api-client.token';
@NgModule({
imports: [
HttpClientModule,
OpraClientModule.registerClient({
serviceUrl: 'https://api.example.com',
token: API_CLIENT,
}),
],
})
export class AppModule {}
Injection
Inject the client by token using @Inject:
import { Injectable, Inject } from '@angular/core';
import { OpraAngularClient } from '@opra/angular';
import { API_CLIENT } from './api-client.token';
@Injectable({ providedIn: 'root' })
export class OrdersService {
constructor(@Inject(API_CLIENT) private client: OpraAngularClient) {}
getOrders() {
return this.client.get<Order[]>('orders').getBody();
}
createOrder(input: OrderInput) {
return this.client.post<Order>('orders', input).getBody();
}
}
Async configuration
When the service URL or credentials are only available at runtime (from a config service or environment), use registerClientAsync:
OpraClientModule.registerClientAsync({
token: API_CLIENT,
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
serviceUrl: config.get('API_URL'),
defaults: {
headers: new Headers({ Authorization: `Bearer ${config.get('TOKEN')}` }),
},
}),
deps: [ConfigService],
})
Using with Angular interceptors
Because AngularBackend delegates to Angular's HttpClient, any Angular HTTP interceptor registered in your module is automatically applied to OPRA requests as well:
// auth.interceptor.ts
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = localStorage.getItem('token');
const authed = token
? req.clone({ setHeaders: { Authorization: `Bearer ${token}` } })
: req;
return next.handle(authed);
}
}
// app.module.ts
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
]
No additional wiring is needed — OPRA requests will carry the Authorization header automatically.
Template usage with AsyncPipe
Since client methods return an Observable, you can bind them directly to Angular templates:
@Component({
template: `
<ul>
<li *ngFor="let order of orders$ | async">{{ order.name }}</li>
</ul>
`,
})
export class OrderListComponent {
orders$ = this.ordersService.getOrders();
constructor(private ordersService: OrdersService) {}
}
Default headers
Set headers applied to every request via defaults:
OpraClientModule.registerClient({
serviceUrl: 'https://api.example.com',
token: API_CLIENT,
defaults: {
headers: new Headers({
'X-App-Version': '2.0',
'Accept-Language': 'en',
}),
},
})