$window / $document in modern Angular
$document becomes the DOCUMENT token. Angular has no built-in window token, so you define a small one or reach the window through document.defaultView.
Before · AngularJS
app.service('ScrollService', function ($window, $document) {
this.toTop = function () { $window.scrollTo(0, 0); };
this.setTitle = function (title) { $document[0].title = title; };
this.width = function () { return $window.innerWidth; };
});After · Angularexport const WINDOW = new InjectionToken<Window | null>('WINDOW', {
providedIn: 'root',
factory: () => inject(DOCUMENT).defaultView,
});
@Injectable({ providedIn: 'root' })
export class ScrollService {
private window = inject(WINDOW);
private title = inject(Title);
toTop() { this.window?.scrollTo(0, 0); }
setTitle(title: string) { this.title.setTitle(title); }
width() { return this.window?.innerWidth ?? 0; }
}What changes
- inject(DOCUMENT) returns the document itself, with no jqLite wrapper and no [0].
- A WINDOW InjectionToken keeps window access mockable in tests, as $window did.
- The Title and Meta services replace direct writes to document.title and meta tags.
Migration tip. Legacy code often skips $window and uses window, localStorage or document directly. Search for those too and route them through tokens, especially if server-side rendering is in the plans.
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