Carlos Cifuentes
AngularJS → Angular reference

$resource .$promise and $resolved in modern Angular

$resource returned an empty object that filled in later, with $promise and $resolved attached. HttpClient returns an observable, and the loading state becomes an explicit value.

Before · AngularJS
vm.user = User.get({ id: $stateParams.id });
vm.user.$promise
  .then(function (user) { vm.title = user.name; })
  .catch(function () { vm.error = true; });

<div ng-if="!vm.user.$resolved">Loading…</div>
<h2 ng-if="vm.user.$resolved">{{ vm.user.name }}</h2>
After · Angular
export class UserDetailComponent {
  private users = inject(UserService);
  id = input.required<string>();

  state = toSignal(
    toObservable(this.id).pipe(
      switchMap(id => this.users.get(id).pipe(
        map(user => ({ status: 'ready' as const, user })),
        startWith({ status: 'loading' as const }),
        catchError(() => of({ status: 'error' as const })),
      )),
    ),
    { initialValue: { status: 'loading' as const } },
  );
}

What changes

  • There is no half-filled object: the template receives a state that is loading, ready or error, and handles each case with @if or @switch.
  • $promise.then chains become RxJS operators, or firstValueFrom when async/await reads better.
  • Instance methods such as $save and $delete become methods of a service that take the entity as an argument.

Migration tip. Angular also has resource APIs (resource, rxResource, httpResource) that package this value, loading and error pattern. Check their stability status in your Angular version before you build on them.

Related

Planning a migration or a micro-frontend platform?

In a 20-minute call you describe your situation and I tell you how I'd approach it. If it isn't worth doing yet, I'll say so.

Message me on LinkedIn