Check out our Angular Book Series.

How to center a div on a page using CSS?

There are a ton of posts about this topic, so I'm just writing this up in hopes I can remember it for this time. How can you center a div on a page? I'm working on a site that where the design requirements were fixed width. These days with mobile devices, I'm a much bigger fan fluid layouts, but that isn't this project.

So, my application needs to be some width, say 500 pixels, and centered within the screen. This is how I'm gonna do it. First, start with an HTML Page:


<html>
<head>
</head>
<body>
<div class="centereddiv">
<h1>Hello You!</h1>
</div>
</body>
</html>

There is an HTML body, with a div inside it, and some more content inside it. First, I'm going to add some CSS for the HTML and Body tags::


html, body {
height: 100vh;
width: 100vw;
background-color: grey;
text-align: center;
}

This sets the HTML and body tags to the height and width of the viewport area using the vh and vw units. I also gave a grey background and told it to center its contents with text-align: center.

Now add some CSS for the centereddiv:


.centereddiv {
width: 500px;
height: 100vh;
background-color: white;
display: inline-block;
text-align: left;
}

A width is specified. I used a pixel width, but this should work fine with a percentage width if you wish. The key part is the display being set to inline-block. This is the piece that tells this div to display in-line basd on the rules of the parent, and the parent uses text-align to center children. That is the magic.

I gave this a height of 100vh, and used text-align to left align the body, but neither matters for the purposes of this sample.

Try it out

It works pretty well.

Naming Conventions Up and Down the Stack

I recently had the opportunity to work with a brand new team building a product from scratch. I never realized how unusual this situation is until I was doing it. As a consultant, I am used to dealing with an existing code base, and do not partake in the arguments around coding conventions that occur before we start writing code. I usually step into existing project, learn the conventions quick, and start contributing. This time, I was center to the debate.

This post will focus on naming conventions, covering every piece of the stack, starting with the database, to the services layer, to REST URLs, to front end code conventions.

As the team created our conventions, we kept passing around links to random blog articles from unknown people about the way things should be. While these articles were often interesting to digest, they were always presented as a canon solution, when in fact they were just the opinion of some random guy on the Internet.

I'm writing this so that next time I can be that one random guy on the Internet whose opinion matters more than yours.

The Database

Let's start with the database. A database is the data store behind your application, and the bulk of projects I work on still use Relational databases, so that is my context. I don't have an opinion on NoSQL databases yet.

The Way it Should Be

Table names should be in ProperCase, sometimes called PascalCase. In ProperCase the first letter of a word is in uppercase, while each consecutive letter is in lowercase. For compound word, the first letter of each word should be in caps.

Here is a simple database structure:

Notice that the table names are plural. This is because every table will contain many items. For example, the Users table has many users. Each row represents a single user, but the table, as a whole, represents all users. You can see ProperCase in action in the linking table, UserRoles. The 'U' from User is in uppercase, and the 'R' from Roles is in uppercase, but all other letters are in lowercase.

Column names should be in camelCase. The camelCase syntax is just like ProperCase, except that the first letter is lowercase instead of uppercase. You see this in columns such as firstName and lastName on the Users table.

The columns should be named singularly. We might state this as an entities table contains many entities, and each entity row has a single column. Populate this sentence with real tables from the diagram: A Users table contains many users, and each user row has a single firstName.

Stored Procedures and Views should use ProperCase in their name, because these are top level elements, just like Tables. Triggers or indexes should use camelCase because these are secondary level elements just like column names.

Why Use Something Different?

Overall, the database naming techniques I love are universal in most projects I've worked on. I did run into one situation where we decide to make the table names singular instead of plural. The reason for this is that the ORM we were using on our services layer generated class names based on the database tables, and we wanted our class names singular instead of plural. Some ORMs, such as hibernate allow us to create a mapping between database table and Java class, but others such as JOOQ do not.

The Backend Services

A service layer is built primarily to communicate with the database, but sometimes it can communicate with other services, such as a Facebook or Twitter API for example. How do we apply naming conventions to this server-side code?

The Way it Should Be

Code is put inside files, and for file names I like to use ProperCase, just as I did for table names in the previous section. Class names mirror the file names, but of course do not have an extension. So, a User.java file would contain a User class.

If I were to model the database structure from above as classes, it would look like this:

The Users table parallels a User class. The Roles table parallels a Role class. Each class instance represents a single record from the database table. The intersection table of UserRoles turned into an array of Role objects in the User class, named roles.

The class names are singular. Every class instance represents a single user, or a single role. A User has a firstName, not Users have a firstName. Property names are in camelCase, which again is just like ProperCase but with the first letter in lowercase instead of uppercase. You see the compound word affect with properties such as firstName and lastName, mirroring what we did at the database level.

The plurality of properties depends upon what the role represents. Since a user has many roles, the name of the roles property is plural. But the User can only have one firstName or lastName, so those properties are singular.

I use similar conventions for files that do not mirror database objects. File names and class names are put in ProperCase. Variables and methods on those classes would be in camelCase. You may have a UserUtils class, for example, that contains a special function to check a User's credentials. This method would be in camelCase structure, one example may be isUserInRole().

Why Use Something Different?

This approach has been consistent with most server-side technology I've had to deal with, from Java to PHP to ColdFusion and even back in the Lotus Notes and iCat days (<-- they were real technologies I swear). I have used this same approach with some NodeJS server-side projects. I have seen an alternate naming approach used on some server side NodeJS projects, but I'll discuss that when I talk about UI code and Angular in a bit.

REST Services

A REST service is a way to load data over a URL. The first time I used anything close to a REST service in a browser application, I loaded data in a hidden iFrame and wrote my own JavaScript to process it and redraw it on the screen. Things are different today.

I have seen a lot of morphing of REST services over the past ten years and the best approach seems like a moving target. I do see some convergence in ideas, and some conventions are growing on me as standards. One example is the use of HTTP Verbs to represent the action being performed. For example, GET requests are used for retrieval, POST requests are used for creation, and PUT Requests perform updates. I'm digressing. The use of these transport mechanisms are unrelated to naming conventions of the REST URLs.

The Way it Should Be

The server name, or domain name, of a URL is never case sensitive in a URL, but the rest of the URL might be, depending on the server implementation. The URL should contain the element being interacted with. Let's look at a sample URL to load all users:

myserver.com/Users

After the domain name, we have the element which is being acted on, in this case Users. A request here would process all users, most likely a GET request would return users. I specifically used ProperCase in the URL to represent Users, and this mirrors how we named the data in the services layer and the data layer. Notice I made users plural, because this request processes all Users.

To update a single user, I recommend creating a singular endpoint:


myserver.com/User

This processes a single User. A POST request would create a new User, and I would expect the body of the request to include a JSON payload representing the new user's data.

A GET request would load a single user, most likely with a URL variable, to specify which user to load, probably like this:


myserver.com/User/1

Would load the User with a userID of 1. A PUT request to the same URL endpoint would update the user with a userID of 1, based on the JSON payload represented in the body.

Why Use Something Different?

I like to make the element in the URL singular if it is operating on a single element, or plural if it is operating on multiple elements. This makes logical sense to me. However, I've seen the argument that the URL should always be plural. A URL like this:


myserver.com/Users/1

Means you are operating on the Users collection where the userID is 1. A PUT would update that User where userID is 1, and a GET would retrieve that User where the userID is 1. I personally feel this approach is less self-explanatory when reading a URL. It makes me think too much.

However, one benefit to this approach is that you'll implement all the HTTP verbs for the same endpoint. When separating out operations on a lot of Users and a single User, it is unlikely I'd implement a PUT or POST request at the Users endpoint, because we will not be creating or updating multiple users in one call. Not having two similar endpoints, with different plurals, makes the programmer need to think less about which end point they need to access and that is a positive good.

Either approach is fine as long as the documentation is there to support it and guide your REST consumers.

User Interfaces

For most of what I do today, the User Interface code includes HTML Templates, JavaScript or TypeScript files, and CSS Files. I haven't done enough mobile development, or desktop application development to have developed a strong pattern about naming conventions in those areas.

The Way it Should Be

When writing UI code, such as JavaScript my first impulse is to model the same structure that I use in the service side. File names and class names follow the ProperCase convention. Variables and methods inside a class use camelCase. I like my UI code side conventions to mirror the server-side conventions as much as possible.

Why Use Something Different?

I have been doing a lot of Angular development as of late. When doing Angular it makes a lot of sense to use the Angular CLI, and the Angular CLI uses a file naming convention called spinal-case. Everything is in lowercase, and compound words are separated by dashes. A class might be something like this:


user-role.ts

The class inside that file would still be named UserRole, so class names are left untouched. Angular components are split up into multiple files: a CSS File, a Test File, a HTML Template file, and a spec file. The Angular CLI also specifies the type of file as part of the file name, .components for components. Creating an Angular component will give you this:

  • user.component.css
  • user.component.html
  • user.component.spec.ts
  • user.component.ts

The class inside the user.component.ts will be UserComponent. Angular uses a similar approach when creating a service, replacing the .component with .service in the file name. Services also do not have CSS or HTML files associated with them.

When building Angular applications, I recommend you use the conventions laid out by the Angular CLI, even if they may be different than guidelines on other aspects of your stack. File names aside, I still use camelCase for functions and variables that are created as part of a class.

Miscellaneous

I wanted to talk about Acronyms, ID fields, and constants a bit, because they are areas where things can digress.

Acronyms

There are two common approaches I've seen to using Acronyms within a database table, class name, variable or method. The first is to put it in all caps, this is my preferred approach. In real world text, acronyms are written in all caps, and our code should mirror that approach. Let's use the acronym TLA--Three Letter Acronym--as a sample.

You might name a class like UserTLA, a variable like this userTLA, and a file name like this UserTLA.extension. If the acronym comes at the beginning instead of the end, I'd name a class like TLAUser, a variable like TLAUser, and a file like TLAUser.extension. This breaks other conventions for the variable name, so you might call it tlaUser, but that is never my preference.

The second approach is to cap the first letter and lowercase the rest. You might name a class like UserTla, a variable like this userTla, and a file name like this UserTla.extension. If the acronym comes at the beginning instead of the end, I'd name a class like TlaUser, a variable like TlaUser, and a file like TlaUser.extension. For variable names, this also breaks the convention of lower casing the first letter of the variable, so sometimes I'll see something like tlaUser. I'm not a fan of using any lowercase in acronyms. Although it may offer more consistency across the code base, than putting the acronym in all caps, it still forces my brain to think harder when reviewing code.

ID fields

An ID field is a special case. ID is not necessarily an acronym, it is more of an abbreviation for identifier. It is common in the database to add the ID postfix to the column that uniquely represents a record--we call this the primary key. I prefer to put ID in all caps, such as userID. Others prefer to capitalize the I and lowercase the D, such as userId. A recent project is using the second convention, lower casing the `d`. It has taken me 6 months, but I've started to reverse the muscle memory I've built up over the years.

Constants

Constants are just like variables in code, but the intent is that they never change. To distinguish constants from regular variables, I often see them created with all caps. For compound words, I separate them with an underscore. A constant might be created like this:


NEW_USER_ID = 0;

An underscore separates multiple words, and this process can be called Snake_Case. This approach seems pretty universal in all technology I have worked with, but I've never seen it required.

Final Thoughts

I want to leave off with this quote from the Google Style Guide:

"Every major open-source project has its own style guide: a set of conventions (sometimes arbitrary) about how to write code for that project. It is much easier to understand a large codebase when all the code in it is in a consistent style."

The emphasis is mine. Conventions are arbitrary. At the end of the day, the naming conventions you use on your project do not matter. I like to encourage consistency because that it makes it easier to maintain the code base, for yourself, your future self, and your replacement. But the actual choices you make are more a matter of personal preference than anything else.

More Reading

How do I access Query Parameters in Angular?

When creating web applications, it is common to add data to a URL that you need to access. For example, one might build an app with a list view that shows a lot of things, such as superheros. Then they have a detail view which shows an expanded detail of a single superhero, such as aquaman.

This post has nothing to do with superheroes. It is all about how to access that item in the URL from an Angular app.

The Setup

I created a default angular application with routing enabled. I created one route, named view1:

const routes: Routes = [
{ path: 'view1/:value', component: View1Component },
{ path: '**', redirectTo: 'view1/default' },
];

The route has a single query param, named value. That is what we'll try to access. The route directs to a new component, which you can create with the Angular CLI:


ng generate component view1

Make sure to replace the main app.component.html with the router outlet:


<router-outlet></router-outlet>

One more thing to do. Open up the view1.component.ts file. We'll need to inject the ActivatedRoute into the component:


constructor(private activatedRoute: ActivatedRoute) { }

You'll also need to import this:


import {ActivatedRoute} from '@angular/router';

You can find the full source here. Let's look at what it takes to access the query param.

Option 1: Params

I set up all these examples in the ngOnInit() method of the View1Component. This is the first:


this.activatedRoute.params.subscribe((params) =>
{
console.log(params.value);
});

The ActivatedRoute has a params Observable. We can subscribe to it, and when it resolves we can access the values. The params object sent to the subscribe function is just an object:

It is a collection of name value pairs and we can access our value using params.value.

Option 2: paramMap

The second option is to access the paramMap. This is also done in the ngOnInit() method against the activatedRoute:


this.activatedRoute.paramMap.subscribe((params ) =>
{
console.log(params['params'].value);
console.log(params.get('value'));
});

paramMap is an observable that resolves to a paramMap. Instead of a generic object, it uses the JavaScript map:

Using a map is a more modern, or ES6, way to handle things instead of using a generic object. The map is better suited for a collection of key value pairs, because it provides an API for accessing values instead of something easily changed.

Option 3: Router Snapshot

The final option I'll show today is to access the snapshot of the activated route. The snapshot mirrors a lot of similar properties to the ActivatedRoute. The main difference is that the snapshot is the route's values at a certain moment in time, whereas the activatedRoute is not. That is why the params, or paramMap, are Observables in the ActivatedRoute, but actual values in the snapshot.

Access the params on the value like this:


console.log(this.activatedRoute.snapshot.params.value);

You'll see something like this:

You can also get at the paramMap, value:


console.log(this.activatedRoute.snapshot.paramMap.get('value'));

You'll see something like this:

Overall, this is similar to using the Observables, except without the Observable part. When accessing the activatedRoute in the ngOnInit, the snapshot should be identical. But, if you need to access something from an unrelated route, or are in the process of switching routes, that is why you'd access the snapshot.

How do you check if a URL variable exists?

When I envisioned this post, I thought I'd write about how to tell if a URL variable exists, but I realized the meat of the post was about finding and accessing the URL variables. If you need to check to see if a value exists, I recommend using the paramMap. For a value that does exist:


if (params.has('value')) {
console.log('it has value');
} else {
console.log('No value');
}

And for a value that won't exist in our demo:


if (params.has('noValue')) {
console.log('it has a novalue');
} else {
console.log('No noValue exists');
}

We use the has() function the params map to check for the existence of the key.

Final Thoughts

Don't forget to grab the code behind this post for runnable samples.

I'm not sure why there are so many ways to get at this data; my preference is to use the paramMap. What about you?

How do I make a TypeScript property that could have multiple types?

I'm working on an app for a client and as with many apps was displaying a list of items. I needed to loop over this list and display items. Every UI framework has some way to do this.

This was an Angular app using TypeScript, so I making use of TypeScript's statically typed nature. My problem was that the objects in this list could be one of two types, let's call those Type1 or Type2. I was running into errors when transpiling the code. I had defined the type like this on the class:


myItems: Type1[];

This code created an array of Type1 arguments. IT wasn't until later that Type2 was added as a possible value in this list.

When updating the code to accommodate for Type2 I realized that sometimes I was receiving errors by accessing Type2 specific properties on a Type1 argument. What was the solution? I used something called Union types. I set up my value like this:


myItems: (Type1 | Type2)[];

This means that myItems can be a mixed array of Type1 and Type2 values.

That works great as long as all properties that you access in Type1 are also in Type2. If a property that you're accessing in one and not the other exists, then you'll get errors--these were the same errors I started with. I solved that issue by adding blank getters to the class definition:


get mySharedProperty(){ return null};

Far from perfect, but functional for my purposes.

Maybe I should have just created an interface and had both Type1 and Type2 extend it?

How do I use a set method to access an conditionally created ViewChild in Angular?

In last week's post I spoke about the problems accessing an Angular ViewChild if it is conditionally created using *ngIf. The solution I proposed there was to use the hidden directive instead of *ngIf. This works, but the caveat is that the child is always created as part of the DOM even if it is not always displayed. I wanted to do another post, providing a different approach

The Setup

I'm going to modify the same application I built last time. It was a simple application created with the Angular CLI and I added one child component. You can get the full code here.

Creating the View

This time, I'm adding a third sample to the app.component.html template:


<button (click)="child3Hidden = !child3Hidden">Toggle Sample 3 Visibility</button>
<br/>
Value Passed into Child: <input type="text" (keyup)="onSample3Change($event)" />
<br/>
<app-view1 #child3 *ngIf="!child3Hidden" ></app-view1>

It uses a value, child3Hidden, to toggle the visibility of the child. Create that in app.component.ts:


child3Hidden = true;

There is an input which is used to change the input value for our app-view1 component:


onSample3Change(event) {
this.child3.value = event.currentTarget.value;
}

This just takes the text input from the AppComponent view and passes it to the ViewChildReference. This is all a similar setup to what we've seen before.

The Problem

Since this ViewChild is conditionally created with *ngIf we cannot access it inside the ngOnInit() and will get an error. The ngOnInit() is like this:


ngOnInit() {
console.log(this.child3);
}

You'll see something like this:

Just an error because the default state of the ViewChild is undefined.

A Solution

Instead of trying to access the ViewChild inside of ngOnInit() we can define the child using get and set methods, like this:


@ViewChild('child3')
set child3(value: View1Component) {
this._child3 = value;
console.log(this.child3);
}
get child3(): View1Component {
return this._child3;
}

Whatever code we want to run in ngOnInit() can be run in the set method, which will get toggled every time the child is created or destroyed. I clicked the button a bunch of times to show you the output:

It is an alternate solution, which works pretty well. The trick part is that whenever you access the ViewChild you'll have to do an undefined check with this approach, something you would not have to do if it were hidden.

Get can get the full code here.

How to Access a Conditionally Created @ViewChild in Angular ngOnInit?

I've been working on an application using Dragula for drag and drop, and dom-autoscroller for scrolling while dragging.

To work, the autoscroller library needs access to the ViewChild, usually set up in ngOnInit. My problem was that we were using *ngIf to hide the scrollable container until things were added to it. As such, the ViewChild was not defined at the time that ngOnInit() ran. This post will explain the problem, and how we solved it.

The Setup

To demonstrate the problem, and our solution, I created a default project with the Angular CLI and added a single component, view1.

The view1 component accepts a single input:


@Input()
value = `default value`;

And the HTML template outputs the value:

view1 works with {{value}}

It is a simple setup. You can get the full code at the Github Repo for my Blog samples.

The Problem

In the app.component.html, add the view child:


<button (click)="child1Hidden = !child1Hidden">Toggle Sample 1 Visibility</button>
<br/>
Value Passed into Child: <input type="text" (keyup)="onSample1Change($event)" />
<br/>
<app-view1 #child1 *ngIf="!child1Hidden" ></app-view1>

The child is hidden based on the child1Hidden value, so create that in the app.component.ts:


child1Hidden = true;

I use a method to update the component's input value. Create as a ViewChild:


@ViewChild('child1') child1: View1Component;

And add the method:


onSample1Change(event) {
this.child1.value = event.currentTarget.value;
}

Note: I know this might be better implemented using HTML properties to update the value, but not all ViewChild interactions are that simple.

Inside the component class, I also want to implement OnInit interface:


export class AppComponent implements OnInit {

And add the ngOnInit() method associated with the interface:


ngOnInit() {
console.log(this.child1);
}

Because the child is hidden by default, this.child1 will be undefined at the time ngOnInit() is run:

Changing the text value before making the child visible will also return errors because our code is accessing an undefined ViewChild reference:

But, once you enable the underlying component:

We are good to go.

The question remains, how do we handle initialization code for that component? I have two solutions, one I'll cover in this post and the second in the next.

Use Hidden

We can replace the *ngIf with the hidden attribute to make this work. Modify our template code:


<button (click)="child2Hidden = !child2Hidden">Toggle Sample 2 Visibility</button>
<br/>
Value Passed into Child: <input type="text" (keyup)="onSample2Change($event)" />
<br/>
<app-view1 #child2 [hidden]="child2Hidden" ></app-view1>

This creates a parallel, similar implementation. It uses child2Hidden instead of child1Hidden. Define it in the app.component.ts:


child2Hidden = true;

Also add the OnSample2Change() method, which updates the input value of the child:


onSample2Change(event) {
this.child2.value = event.currentTarget.value;
}

Be sure to define child2 as a formal ViewChild:


@ViewChild('child2') child2: View1Component;

And output child2 inside ngOnInit():


console.log(this.child2);

Rerun the app:

There are no errors in the console even though the view is not shown.

The reason this works is that when you conditionally show or hide a component using *ngIf Angular removes, or adds it, to the DOM. So, if the value is false, the ViewChild is undefined because the component does not exist. When we use the hidden directive, the component may be hidden from view, but is still created as part of the DOM.

Final Thoughts

I have mixed feelings about using hidden to get around the problem because I am not convinced that it is a good idea to create every child as part of the DOM if it is not needed or being used at the moment. Next week I'll show you a different approach.

You can get the Get can get the full source code, and a peak at next week's sample.

How to access a Constant in an Angular View Template?

Angular provides a mechanism for sharing instance variables inside a component with that template's view component, but how do you access a constant in a view template? Constants in TypeScript are not created as instance variables on a class, so they are not easily accessible inside the HTML template. This post will show you how.

The Setup

Create a new project with the Angular CLI. You can also get access to the full source code in my Blog Sample Github Repo.

Create the Constant File

Create a file in the root directory named constants.ts. Add in a single constant:


export const MY_TEST_CONSTANT = `Something`;

This is pretty simple.

Load the Constant in the Component

The trick to access the constant's value inside the view template is to copy the Constant value to an instance variable in the component. Open up the app.component.ts on your new project, and add a line like this:


myConstant = MY_TEST_CONSTANT;

You'll also need to import the constant:


import {MY_TEST_CONSTANT} from './Constants';

Update the View Template

Now the View Template can access the constants value. Open up the app.component.html file, ad add something like this:


<strong>Here is your Constant</strong>: {{myConstant}}

You're no longer referencing a global constant, but rather a component instance variable that has the same value as the global constant.

It works:

You can use the myConstant value as part of any Angular element in the HTML template including *ngIf, *ngFor, ngModel, or whatever you need.

Don't forget to check out the full code.

How to spy on a Property with Karma?

When writing unit tests, SpyOn, is used to watch and manipulate a method call, potentially returning your own data. This is used to easily mock external component calls so that your unit test can focus on the class in question without worrying about complications or side affects from external dependencies. I found myself in a situation where I had a class and that class had a read only get() property. I was creating my own Angular service wrapper for the Dragula drag and drop library. I was exposing some drop and remove listeners get methods.

I wanted to control the results returned from that get method. This was not a situation where I could set the underlying value because there was no set method. But, spyOn would not work because a get() method is viewed as a property, not a method. The class code was conceptually like this:


export class MyClass {

constructor(private dragula: DragulaService){
}

get dropListener(){
return this.dragula.drop('myDragulaGroup');
}
}

My code was using Angular, so the DragulaService was injected into this component, and the dropListener was exposed via a get.

For the purposes of unit testing, I want complete control over that drop listener Observable. Thankfully, spyOnProperties would give me that control.

The unit test would be a bit like this:


it("Should spy on Observable", () =>
{
const myClassInstance = new MyClass();

let dropObserver: Observable<any>;
const dropObservable: Observable<any> = Observable.create( ( ObserverArg: Observer<any>) => {
dropObserver= ObserverArg;
}

mySpy = spyOnProperty(myClassInstance, 'dropListener', 'get').and.returnValue(dropObservable);

I'm gonna take a quick break to explain spyOnProperty. It takes three parameters:

  • Class: The class instance that contains the property you want to watch.
  • Property: The name of the property being watched.
  • Accessor: The Access Type of the method being watched, in this case get.

Note that we are storing the results of the spyOnProperty in the mySpy variable. This is optional when using spyOn, but for spyOnProperty it is required. The unit test could would continue:


const val = myClassInstance.dropListener;

All that line does is access the dropListener property inside the class, which should trigger the spy. Now we can test against the access:


expect(mySpy ).toHaveBeenCalled();
});

In a more advanced unit test, we could subscribe to the dropListener inside the test, and use dropObserver.next() to trigger the result handler in an async block.

Can I create a Provider in Angular without listing it in the provider array?

This was something new I just discovered. You can create an Angular provider, as a singleton and do not have to list it in the provider array. This post will show you how.

The setup

To set up this project, I used the Angular CLI to create a new project. Then I created two services: ServiceOneService and ServiceTwoService. I also created two views: view1 and views2. You can find the code behind this project in this blog's GitHub repo.

Modify the main app.component.html template to include the two views:


<app-view1></app-view1>
<br/>
<app-view1></app-view1>

Create the services

Service1 should look something like this:


import { Injectable } from '@angular/core';
@Injectable()
export class ServiceOneService {
text = `from service one`;
constructor() { }
}

It is created as injectable, and has a single property. Open the app.module add this as a provider:


providers: [
ServiceOneService
],

Service2 should look something like this:


import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ServiceTwoService {
text = `from service two`;
constructor() { }
}

The service looks almost identical, even having the same text property on it. The big difference is in the injectable metadata, we added a providedIn: 'root'. This is the trick to creating a provider without defining it as a provider. means that the first time the service is injected, Angular will create the Singleton just as if it were set up as an explicit provider.

The Views

Open up the TypeScript file for view1 and view2 and load the services:


constructor(public service1: ServiceOneService, public service2: ServiceTwoService) { }

Open up the HTML component for each view and paste this in there:


From Service 1, set up as traditional provider:
<input type="text" [(ngModel)]="service1.text" >
<Br/><Br/>
From Service 2, using providedIn = root:
<input type="text" [(ngModel)]="service2.text">

This just puts an input on the screen, one binding to the service1.text, and the other binding to service2.text.

Since we're using ngModel don't forget to load the import the FormsModule into the appModule:


imports: [
BrowserModule,
FormsModule
],

Run the Code

Now run the code and load it in a browser. When you type in the service 1 input in one component, the input in the other component should also change:

This is what is normal and we're used to because we set up Service1 as a provider and the single instance should be shared between the two components.

Now try to type in the service 2 input. The values also change:

This surprised me, since Service2 is not set up as a provider. However, the `providedIn` metadata tells Angular to create Service2 as a service. It works like magic.

Get The Full Source for this Sample.

How do I set up a Proxy Server with Angular?

This is an excerpt from my Learn With series on Angular 7, which came out about a month ago. I wrote this up for the DotComIt newsletter, and thought I'd share it here too.

This post details how to use Angular's server side proxy to connect the Angular CLI dev server to access the NodeJS application server without having to worry about cross domain issues. The Angular CLI dev server is not set up to run normal server-side code, like custom NodeJS, ColdFusion, PHP, or Java. Instead the preferred approach is to set up a server-side proxy to redirect your Angular calls to your other remote servers.

The first step is to create a proxy config file. Name the file proxy.conf.js and put it in the root directory of the project, where the angular.json file is located. It should start as an empty file, but let's create a constant:


const PROXY_CONFIG = [{ }]
module.exports = PROXY_CONFIG;

The code also exports the configuration. The PROXY_CONFIG is an array of objects, although for our case we'll just have a single object. First, add a context:


context: [ "/nodejs" ],

The context value says "Whenever a URL comes in that contains `/nodejs`, we'll redirect it elsewhere. Exactly where you want to redirect it depends on your local configuration. Add a target property:


target: "http://127.0.0.1:8080/",

In the case of NodeJS, we're redirecting the request to a different port on localhost.

Set the secure to false:


secure: false,

In local dev environments I never set up HTTPS or use secure URLs like I would in a production environment. There are a few other values that may be needed or not depending on your local setup. I'll go over them here for completeness.

First, you can have the proxy to rewrite the path:


pathRewrite: { "^/nodejs": "" },

You'll only need a path rewrite if you need to modify the URL. For example, if your API will call '/nodejs/authenticate', but your actual service is set to '/authenticate', then this will allow you to direct your service call to the proper code.

Another value to be aware of is changeOrigin:


changeOrigin: true

You'll only need to use the changeOrigin value if you are setting up a local alias for your NodeJS sample. For example, if your NodeJS server is set to listen to requests on 'local.nodejs.learn-with.com' then this will tell the proxy it is okay to rewrite domain from localhost to 'local.nodejs.learn-with.com'.

The last value I want you to be aware of is the debug:


logLevel: "debug",

When you set this property, the console will give you a lot of details of how the proxy is working and rewriting URLs. It can be handy when you need to debug things.

Final Thoughts

I hope you're doing well in this holiday season.

Keep up to date by reading DotComIt's Monthly Technical Newsletter

More Entries

All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.