Angular.js

Learning resources

Tutorials

Misc StackOverflow questions

SCSS

Using CSS classes to style the parent div of a component

  • Every component has a “parent” div that doesn’t show up in the actual template (.html) file, but shows up in the rendered HTML as <your-component-name>. Sometimes you may want to apply CSS classes to that div, but you can't just add class="your-class-name" in the template file because the div doesn’t show up there.

  • If you want the class to always be applied, add a line like this to the top of your component’s class definition: @HostBinding('class.your-class-name')

  • If you want the application of the CSS class to depend on a prop passed into the component, add a line like this: @HostBinding('class.your-class-name') useMyClassName: boolean = false;

  • You will then need to update the SCSS file to have the selector as :host(.your-class-name) if you want SCSS rules nested within that class to work. Again, if you don’t add :host(), any nested rules just won’t show up.

Udemy - Max Schwarzmüller - Master Angular: The Complete Course

  • https://www.udemy.com/course/the-complete-guide-to-angular-2/

  • Max is a great teacher. I basically learned Vue.js from him. Yes, at times the official docs will provide just-as-good of an explanation of something, but even just an incrementally-better explanation that what you’d find in the docs (like, with clear examples) is worth a lot.

  • I’m omitting some course sections from my notes that were just course projects or less-important information.

Summary of key ideas from the course I want to remember

Section 2: The Basics
  • Angular uses modules to bundle components into packages.

  • Summary of databinding syntax:

    • String interpolation is the same as Vue.

    • Property binding: [property]="expression" (Vue syntax is :property="expression" )

    • Event binding: (event)="functionToCall()" (Vue syntax is @event="functionToCall")

    • Two-way binding: [(ngModel)]="variable" (Vue syntax is v-model="variable")

    •  

Section 1: Getting Started

  • This was very basic stuff that I didn’t care to take notes on, like explaining what TypeScript is, how to start a project, how to install Angular, advice for how to get the most out of the course, etc.

Section 2: The Basics

How an Angular app gets loaded and started
  • The index.html file in your repo is the file served by the server.

  • Look at the app.component.ts and look at the selector attribute (app-root). That's how the server knows to replace the app-root in the index.html with our app.component.html code.

  • When ng serve rebuilds the project, the injected JavaScript imports will be updated.

  • The code in main.ts file is the first code that gets executed. The bootstrapModule method is what gets the app started. You can see it loads the AppModule which is in app.module.ts. In that file you can see all the components that should be known to the app being registered.

Components are important!
  • The core idea of Angular is that projects are made up of components, each of which can have its own HTML code / logic / styling.

  • We start projects with a "root" component (AppComponent), in which we'll nest other components.

Creating a new component
  • Generally, in an Angular CLI project, all your app-related content will go into an app folder.

  • Each component should generally have its own folder, named after the component.

  • A component is just a TypeScript class.

  • The naming convention for naming a component class is to have the name of the component and then Component, so, like, ServerComponent.

  • To get the class working as an Angular class we need to add the @Component() decorator.

  • We also need to configure the class, giving Angular information it needs to use the class properly. We do this by passing an object to the @Component() decorator.

  • We need to specify the HTML selector for the component and the path to the template code.

Understanding the role of AppModule and component declaration
  • Angular uses modules to bundle components into packages.

  • Just as with components, we create a module by adding a decorator (@NgModule) with an object configuration to a plain JavaScript class.

  • The bootstrap config option tells Angular which component to use as the entry point.

  • The declarations config option tells Angular to include the specified components in the module.

  • The imports config option allows you to include / use other modules in your module. So it's like the requirements.txt in Python.

Using Custom Components
  • In this video he just shows himself adding his custom component’s HTML tag to the root app component’s template file.

Creating Components with the CLI & Nesting Components
  • You can create new components with the CLI. Make sure you have the ng serve command running in one terminal window when you run this command in another window.

  • The command is ng generate component <component-name> or ng g c <component-name> for short.

  • The ‘nesting’ referred to in the lesson title doesn’t refer to the file structure of the code, as the two components he uses to demonstrate ‘nesting’ are at the same level as each other. He just creates a servers component which has as its template two instances of the server component.

Working with Component Templates
  • You can define your component template within the .ts file using the same template attribute you normally pass the path to the template file.

  • To have newlines in the template in the .ts file, wrap the template code in backticks.

Working with Component Styles
  • He shows a simple example of adding custom CSS to the component’s CSS file (changing the color of an h3 tag).

  • You can pass multiple CSS files to the styles component attribute.

  • You can add your custom CSS directly in the .ts file just like with the template code, which is nice when you have very little custom CSS for the component.

Fully Understanding the Component Selector
  • You can have your selector be an HTML attribute by enclosing the selector name in square brackets:

    • Example selector value: '[app-servers]'

    • Example usage in a template: <div app-servers></div>

  • You can also have the selector be a CSS class:

    • Example selector value: '.app-servers'

    • Example usage in a template: <div class="app-servers"></div>

What is Databinding?
  • Databinding is communication between your TypeScript code and the template.

  • There are different forms that this communication can take:

    • If we want to output data from our TS code to the template, we can use:

      • String interpolation ({{ data }}), or…

      • Property binding ([property]="data")

    • If we want our TS code to react to user events, we can use:

      • Event Binding ((event)="expression")

    • We can combine both with “two-way binding” ([(ngModel)]="data")

String Interpolation
  1. Use the syntax {{ expression }} to do string interpolation in a template.

  2. The expression just needs to resolve to a string or something that can be converted to a string (like a number).

  3. When defining custom methods in a component class, you just define them at the top level of the class. You don’t nest them in a “methods” object or something.

Property Binding
  1. He spends a fair amount of time showing himself creating a setTimeOut function in the constructor to update a variable, which isn’t relevant to the topic at hand.

  2. To bind the value of a property to an expression, wrap the property in square brackets like this:

    <button [disabled]="!allowNewServer"></button>
  3. So it's like v-bind: or : in Vue:

    <button :disabled="!allowNewServer"></button>
Property Binding vs String Interpolation
  1. Use string interpolation when you want to display some string in the template, use property binding when you want to control the value of a property using an expression.

  2. Remember not to use curly braces where you’re supposed to put an expression.

Event Binding
  1. He likes to name his component functions that called by some event starting with “on”, like onEventCreated

  2. Angular uses parentheses to indicate events:

    <button (click)="onEventCreated()"></button>
  3. So it’s the equivalent of @ in Vue: <button @click="onEventCreated">

    1. But you need to include the parentheses when calling a function in Angular.

Bindable Properties and Events
  1. To see what properties and events an HTML element offers, use console.log() on the element.

  2. The MDN docs also have lists of the properties and events available for HTML elements; search Google and you should find the relevant docs.

Passing and Using Data with Event Binding
  1. We can capture event data by passing the $event object to the function we call.

  2. The target attribute of the event object is the HTML element.

  3. The value attribute of an input event object is the user-entered value of the input.

Two-Way Databinding
  1. He just explains what two-way binding is. It’s the same as v-model in Vue.

Understanding Directives
  1. Directives are instructions in the DOM.

  2. Component tags in our templates are an example of such instructions.

  3. There are directives with a template (like components) and directives without templates.

  4. Typically you’ll create directives that are placed in your templates like HTML attributes.

  5. He gives an example of an appTurnGreen directive.

  6. Example code:

Using ngIf to Output Data Conditionally
  1. So far we haven’t used any directives aside from components (which are considered directives).

  2. The syntax is *ngIf ="expression"

    1. The * identifies this directive as a “structural” directive, meaning it can change the structure of the DOM.

Enhancing ngIf with an Else Condition
  1. The syntax is actually pretty different from Vue:

    1. The # identifies a local reference.

Styling Elements Dynamically with ngStyle
  1. The other type of directives are “attribute directives”, which don’t have a leading “*”.

  2. To use the ngStyle directive we need to surround it in square brackets.

    1. His example: <p [ngStyle]="{backgroundColor: getColor()}">

  3. NW note: The equivalent in Vue is :style=

  4. He spends a minute making sure that we understand that the square brackets (property binding) and the directive name are two different features of Angular.

Applying CSS Classes Dynamically with ngClass
  1. ngClass allows you to dynamically set CSS classes.

  2. This works like in Vue.

  3. It takes an object where the keys are the CSS classes and the values are expressions to determine whether to enable that CSS class.

Outputting Lists with ngFor
  1. The syntax is *ngFor="let obj of objs"

Getting the Index when using ngFor
  1. The syntax is *ngIf="let obj of objs; let i = index"

Section 4: Debugging

Understanding Angular Error Messages
  1. Open the Chrome devtools and check the console.

  2. He examines the following example error that shows up in the console:

  3. The first important part is that it is telling us the error is in the ./AppComponent component.

  4. The second important clue is that it’s in the “inline template”, with line number 4 and column number 6.

    1. Unfortunately the “line 4, column 6” part is not helpful to us, because that’s the line in the compiled version of the code rather than the source code.

  5. The last piece of important information is the message “Cannot read property ‘push’ of undefined”.

    1. This is how we’ll actually find the error: there’s only one place where we call “push” in our AppComponent code.

  6. Another way to find the error would be to notice it is raised when we click the button, and therefore is likely to be somewhere in the function that handles that button click.

  7. The issue in this particular case is that we’re defining the servers variable but not setting its initial value to an empty array.

  8. So the takeaway is: try to use the error message in the console to identify which file/component is the source of the error, and the particular error it’s encountering in that file/component, and that should hopefully give you enough information to track down what’s happening.

Debugging Code in the Browser Using Sourcemaps
  1. Sometimes you’ll have problems that don’t produce an error message, like the last item in a list not being deleted when you click on it.

  2. In the Chrome Devtools, go to the Sources tab.

  3. The main.bundle.js is the actual file being used by the browser, but it’s not our original source. If we try to set a breakpoint in the main.bundle.js file Chrome will jump us to the relevant source file.

  4. These file support “source maps” allow Chrome to map the bundled JavaScript code that’s actually getting executed to the original source code.

  5. While the code is halted by a breakpoint, you can hover over variables in the code to see their values.

  6. To directly browser your source files, go to the webpack:// section in the left sidebar of the “Sources” tab, then expand the ./src/app/ directory.

Section 5: Components & Databinding Deep Dive

Module Introduction
  1. We’re going to dive deeper into components and databinding.

  2. We’re going to improve an example project using components and databinding.

Splitting Apps into Components
  1. Our example app has two text fields that allow us to define a “Server Name” and a “Server Content”, and two buttons that allow us to “Add Server” or “Add Server Blueprint”, with the only difference between a server and a server blueprint being how the server content text field is displayed (with all servers and blueprints also being shown on this single page).

  2. Right now all the code is in our AppComponent class.

  3. We could create a new component for where we create new servers, and a component for displaying a created server/blueprint.

  4. He uses the CLI to create the two new components: ng g c component-name --spec false

    1. --spec false makes it so that no testing files will be created for this component.

  5. He cuts the relevant code from the AppComponent template file and component file and pastes it into the new components.

  6. He wants to keep the servers variable in the AppComponent because we need to access it from the two child components (the “input” component and the “display” component).

  7. Breaking up the code this way has broken our app because we don’t have a way to pass data between our components. We’re going to fix that next.

Property & Event Binding Overview
Binding to Custom Properties
Assigning an Alias to Custom Properties
Binding to Custom Events
Assigning an Alias to Custom Events
Custom Property and Event Binding Summary
Understanding View Encapsulation
More on View Encapsulation
Using Local References in Templates
@ViewChild() in Angular 8+
Getting Access to the Template & DOM with @ViewChild
Projecting Content into Components with ng-content
Understanding the Component Lifecycle
Seeing Lifecycle Hooks in Action
Lifecycle Hooks and Template Access
@ContentChild() in Angular 8+
Getting Access to ng-content with @ContentChild
Wrap Up

 

Section 7: Directives Deep Dive

Section 9: Using Services & Dependency Injection

Section 11: Changing Pages with Routing

Section 13: Understanding Observables

Section 15: Handling Forms

Section 17: Using Pipes to Transform Output

Section 18: Making Http Requests

Section 20: Authentication & Route Protection in Angular

Section 21: Dynamic Components

Section 22: Angular Modules & Optimizing Angular Apps

Section 23: Deploying an Angular App

Section 24: Standalone Components

Section 25: Angular Signals

Section 26: Using NgRx for State Management