Querying the Database from Angular
One of possible improvements is to perform queries against MongoDB directly from Angular Universal. In this lesson you will create a service which does this job.
MongoService#
Generating the service#
Start your work by generating a new service that will be used to connect to MongoDB:
ng g s mongo --skipTests
To apply the Don't Repeat Yourself (DRY) principle, you will utilize this service in the api.ts file. In other words, you will move the database querying logic from api.ts to MongoService
. A naive implementation could look like this:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class MongoService {
private dbUrl =
'mongodb+srv://angular-universal:[email protected]';
constructor() {
//connect to database
}
public async retrieveFromDb(
collectionName,
project = {},
query = {}
): Promise<any[]> {
return [];
}
}
The prepared class can now be imported into api.ts instead of the current MongoDB-related logic. Unfortunately, this is not trivial. Try to inject the prepared service anywhere in your application, such as ProductsService
:
import { MongoService } from './mongo.service';
@Injectable({
providedIn: 'root',
})
export class ProductsService {
private API_URL = `${environment.apiBasePath}/api`;
constructor(
private httpClient: HttpClient,
private mongoService: MongoService
) {}
Now run the Angular compiler:
npm run build:ssr
Take a look at the content of the dist/browser/main***.js bundle that is sent to the end user's browser:

That's a severe security breach: you disclose your database connection string to every user of your application!
Angular Universal is an excellent solution as it enables sharing the code base between browser and server bundles. While it's a great way to avoid duplicating business logic in your project, it might lead to serious security breaches and compromising sensitive data such as database connection strings!
Using the isPlatformBrowser()
and isPlatformServer()
methods doesn't help here because the same code base is still used on both platforms. This is how the isPlatformXXX()
method used in I18nService
is translated to a JavaScript bundle:
this.userLang=function(e){
return"browser"===e
}
(this.platformId)?window.navigator.language:(
this.request.headers["accept-language"]||"").substring(0,5)}
This page is a preview of The newline Guide to Angular Universal