Did you encounter the “ref” information from backend of Asp.net core?
0:{$id: '2', id: 26, roomId: 1, guestId: 1, checkInDate: '2025-09-18T00:00:00', …}
1:{$ref: '6'}
2:{$ref: '12'}
3:{$ref: '9'}
4:{$ref: '16'}
This JSON structure (with $ref and $id) indicates that your API is using JSON Reference to handle circular dependencies or shared objects (a common approach when serializing entities with relationships, like Booking → Room → Booking). Here’s how to fix Angular’s handling of these references:
What’s Happening
$id: '2'marks an object as uniquely identifiable (e.g., the firstBooking).{$ref: '6'}tells Angular: “This object is a reference to the object with$id: '6'”.
Angular doesn’t natively parse $ref/$id by default, so it treats these as plain objects (leading to undefined or broken data for referenced records).
How to Fix It
You need to resolve JSON references in Angular before using the data. Here’s how:
Step 1: Install a JSON Reference Resolver
Use a library like json-refs to resolve references. Install it via npm:
npm install json-refs
Step 2: Create a Helper Service to Resolve References
Create a service to fetch data and resolve $ref/$id before passing it to components:
// reference-resolver.service.ts
import { Injectable } from '@angular/core';
import * as JsonRefs from 'json-refs';
@Injectable({
providedIn: 'root'
})
export class ReferenceResolverService {
resolveReferences<T>(data: any): T {
const options = {
resolveCirculars: true, // Handle circular references
loaderOptions: {
processContent: (res: any) => JSON.parse(res.text())
}
};
return JsonRefs.resolveRefs(data, options).then((result: any) => {
return result.resolved as T;
});
}
}
Step 3: Use the Resolver in Your Booking Service
Modify your service to resolve references before returning data:
// booking.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ReferenceResolverService } from './reference-resolver.service';
import { Booking } from './booking.model';
@Injectable({
providedIn: 'root'
})
export class BookingService {
private apiUrl = 'https://your-api-url/bookings';
constructor(
private http: HttpClient,
private refResolver: ReferenceResolverService
) { }
getBookings(): Observable<Booking[]> {
return this.http.get<any>(this.apiUrl).pipe(
map((apiResponse: any) => this.refResolver.resolveReferences<Booking[]>(apiResponse))
);
}
}
Step 4: Ensure Your Interface Matches the Resolved Data
Update your Booking interface to match the structure after references are resolved (no more $ref/$id):
// booking.model.ts
export interface Booking {
id: number;
roomId: number;
guestId: number;
checkInDate: string;
checkOutDate: string;
room: Room; // Now a concrete object (not a $ref)
guest: Guest; // Now a concrete object (not a $ref)
}
export interface Room {
id: number;
name: string;
// Other room properties
}
export interface Guest {
id: number;
name: string;
// Other guest properties
}
Why This Works
json-refsprocesses the API response, replacing$refwith the actual referenced object.- Angular now receives a plain array of
Bookingobjects (no more$ref/$id), so all records render correctly.
Alternative: Configure Backend to Avoid $ref
If you prefer the backend to send “flat” JSON (no references), configure Entity Framework/JSON serialization to avoid generating $ref/$id:
In ASP.NET Core (.NET 6+), update Program.cs to ignore circular references (which disables $ref generation):
builder.Services.AddControllers()
.AddJsonOptions(options => {
options.JsonSerializerOptions.ReferenceHandler = System.Text.Json.Serialization.ReferenceHandler.IgnoreCycles;
});
This tells the serializer to duplicate objects instead of using references, so Angular receives plain JSON (no $ref/$id). Use this if you don’t want to add a reference resolver in Angular.
By resolving JSON references (either in Angular or via backend configuration), all Booking records will load correctly without $ref/$id issues.
5718

被折叠的 条评论
为什么被折叠?



