Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar correction. Thanks to @ChereeNielson #39

Open
wants to merge 17 commits into
base: stackblitz
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .gitbook/assets/angular.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/lab (1).jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/lab.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/nggirls-banner-transparent.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/slogen (1).png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/slogen (2).png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .gitbook/assets/slogen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# Angular Tutorial for Beginners -
# About

# Creating a Todo-List App
## Angular Tutorial for Beginners -

## Creating a Todo-List App

This tutorial will take you step by step on how to create your own todo list application using Angular \(version 2 and above\). Through the tutorial, we'll be using the Angular-CLI, save data in the local storage and deploy the code to Github Pages.

#### [StackBlitz version - use an online editor](https://ng-girls.gitbook.io/todo-list-tutorial/v/stackblitz/)

This tutorial is open source and is written by the community. Please feel free to send any suggestions and pull requests. Special thanks to the members of** Angular AfterHours meetup group **for kickstarting this tutorial during a [special meetup event](http://www.meetup.com/Angular-AfterHours/events/235151422/)!

The tutorial is used in the [ngGirls](http://ng-girls.org) workshops. You are welcome to use it in your own workshop and we'd love to hear about it! - write us to: [[email protected]](/mailto:[email protected]).
The tutorial is used in the [ngGirls](http://ng-girls.org) workshops. You are welcome to use it in your own workshop and we'd love to hear about it! - write us to: [[email protected]](mailto:[email protected]).

![](/assets/ngGirls banner transparent.png)
![](.gitbook/assets/nggirls-banner-transparent%20%281%29.png)

![](/assets/slogen.png)
![](.gitbook/assets/slogen.png)

**About the lead author:** Shmuela Jacobs is a senior front-end developer and consultant mastering Angular. During her academic studies \(M.Sc. in Information Management Engineering and B.Sc. in Physics\) she has combined her passions of coding and teaching as a software developer, teaching assistant, science museum guide, and researcher. Today she continues to enjoy these activities as a full-time front end developer, sharing her knowledge and experience in meetups and conferences. Shmuela is the founder of ngGirls and the organizer of Angular AfterHours meetup group.

36 changes: 18 additions & 18 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
# Summary
# Table of contents

* [About](README.md)
* [Introduction](introduction.md)
* [Installations](installations.md)
* [Angular kicks in](angular_kicks_in.md)
* [Angular kicks in](angular-kicks-in.md)
* [Component](component.md)
* [A new component](a_new_component.md)
* [A new component](a-new-component.md)
* [Class](class.md)
* [Property binding](property_binding.md)
* [Event binding](event_binding.md)
* [Element ref - \#](element_ref_-.md)
* [The To Do list](the_list.md)
* [New component: todo-item](new_component_todo-item.md)
* [Add items](add_items.md)
* [Refactor App Component](refactor_app_component.md)
* [Adding Style](adding_style.md)
* [Property binding](property-binding.md)
* [Event binding](event-binding.md)
* [Element ref - \#](element-ref.md)
* [The To Do list](the-to-do-list.md)
* [New component: todo-item](new-component-todo-item.md)
* [Add items](add-items.md)
* [Refactor App Component](refactor-app-component.md)
* [Adding Style](adding-style.md)
* [Service](service.md)
* [Add more abilities to service](add_more_abilities_to_service.md)
* [Local storage](local_storage.md)
* [Remove item](remove_item.md)
* [Adding a checkbox](adding_a_checkbox.md)
* [Deploy to GithubPages](deploy_to_githubpages.md)
* [Enrich the todo-item component](enrich_the_todo-item_component.md)
* [Appendix 1: Generating a new project](generating_a_new_project.md)
* [Add more abilities to service](add-more-abilities-to-service.md)
* [Local storage](local-storage.md)
* [Remove item](remove-item.md)
* [Adding a checkbox](adding-a-checkbox.md)
* [Deploy to GithubPages](deploy-to-githubpages.md)
* [Enrich the todo-item component](enrich-the-todo-item-component.md)
* [Appendix 1: Generating a new project](appendix-1-generating-a-new-project.md)
* [Appendix 2: Tutorial Extensions](appendix-2-tutorial-extensions.md)

52 changes: 29 additions & 23 deletions a_new_component.md → a-new-component.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,37 @@
# A new component

In this chapter we will write a whole new component. It will allow us adding an item to the todo list. It will be composed of the HTML elements `input` and `button`. We will call it Input-Button-Unit.
In this chapter we will write a whole new component. It will allow us adding an item to the todo list. It will be composed of the HTML elements `input` and `button`. We will call it Input-Button-Unit.

We'll use Angular-CLI to generate all the needed files and boilerplate for us. Angular-CLI takes commands in a terminal window. This doesn't mean that we have to stop the process `ng serve`. Instead, we can open another terminal window or tab and run the additional commands from there. The changes will be reflected immediately in the browser.

Open another terminal tab and run:

```cmd
```text
ng g c input-button-unit
```

As we've seen before, `ng` is the command for using Angular-CLI. `g` is a shorthand for `generate`. `c` is a shorthand for `component`. `input-button-unit` is the name we give to the component.

So the long version of the command is (don't run it):
So the long version of the command is \(don't run it\):

```
```text
ng generate component input-button-unit
```

Let's take a look of what Angular-CLI created for us.

It created a new folder called `src/app/input-button-unit`. There are three files there (or four if you're not using inline-template):
It created a new folder called `src/app/input-button-unit`. There are three files there \(or four if you're not using inline-template\):

* `input-button-unit.component.css` - this is where the style that's specific to the component will be placed.
* `input-button-unit.component.spec.ts` - this is a file for testing the component. We will not deal with it in this tutorial.
* `input-button-unit.component.ts` - this is the component file where we will define its logic.
* `input-button-unit.component.html` - this is the HTML template file, if you're not using inline-template.


Open the file `input-button-unit.component.ts`. You can see that Angular-CLI has generated the component's configuration for us, including its selector, which is the name we gave preceded by the prefix `app`, and a default template:

```ts
// src/app/input-button-unit/input-button-unit.component.ts

{% code-tabs %}
{% code-tabs-item, title="src/app/input-button-unit/input-button-unit.component.ts" %}
```typescript
@Component({
selector: 'app-input-button-unit',
template: `
Expand All @@ -43,18 +42,20 @@ Open the file `input-button-unit.component.ts`. You can see that Angular-CLI has
styleUrls: ['./input-button-unit.component.css']
})
```
{% endcode-tabs-item %}
{% endcode-tabs %}

> The prefix `app` will be added to the component selector of all the components you will generate. This is to avoid name conflicts with other components and HTML elements. For instance, if you create a component named input it will not conflict with HTML's `<input />` element, since its selector will be `app-input`.

>`app` is the default prefix, which is good for your main application. However, if you're writing a library of components to be used in other projects, you should choose a different prefix. For example, the [Angular Material](https://material.angular.io/) library uses the prefix `mat`. You can create a project stating the prefix of your choice using the flag `--prefix`, or change it afterwards in the file `.angular-cli.json`.
> The prefix `app` will be added to the component selector of all the components you will generate. This is to avoid name conflicts with other components and HTML elements. For instance, if you create a component named input it will not conflict with HTML's `<input />` element, since its selector will be `app-input`.
>
> `app` is the default prefix, which is good for your main application. However, if you're writing a library of components to be used in other projects, you should choose a different prefix. For example, the [Angular Material](https://material.angular.io/) library uses the prefix `mat`. You can create a project stating the prefix of your choice using the flag `--prefix`, or change it afterwards in the file `.angular-cli.json`.

We can use this component as is and see the result!

Open the root component file, `app.component.ts` and add the app-input-button-unit tag anywhere inside the template (remember we refactored the root component to have an inline template):

```html
// src/app/app.component.ts
Open the root component file, `app.component.ts` and add the app-input-button-unit tag anywhere inside the template \(remember we refactored the root component to have an inline template\):

{% code-tabs %}
{% code-tabs-item, title="src/app/app.component.ts" %}
```markup
template: `
<h1>
{{ title }}
Expand All @@ -63,32 +64,37 @@ template: `
<app-input-button-unit></app-input-button-unit>
`,
```
{% endcode-tabs-item %}
{% endcode-tabs %}

Check what's new in the browser!

Let's add some content in our new component. First, add a `title` member which we will use as the todo item's title:

```ts
// src/app/input-button-unit/input-button-unit.component.ts

{% code-tabs %}
{% code-tabs-item, title="src/app/input-button-unit/input-button-unit.component.ts" %}
```typescript
export class InputButtonUnitComponent implements OnInit {
title = 'Hello World';
...
```
{% endcode-tabs-item %}
{% endcode-tabs %}

It will not interfere with the `app-root` component's `title`, since each component's content is encapsulated within it.

Next, add some content and an interpolation of the title member in the template:

```html
// src/app/input-button-unit/input-button-unit.component.ts

{% code-tabs %}
{% code-tabs-item, title="src/app/input-button-unit/input-button-unit.component.ts" %}
```markup
template: `
<p>
The title is: {{ title }}
</p>
`,
```
{% endcode-tabs-item %}
{% endcode-tabs %}

Check out the result!

Expand Down
16 changes: 8 additions & 8 deletions add_items.md → add-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@

We want to add items to our list. With Angular we can do this easily and see the item added immediately. We will do this from within the `inputComponent` we created before. We'll change it so when hitting the Enter key or clicking the submit button, the value of the input box will become the title of the new item. And the new item will be added to the list.

But we don't want the todo-input component to be responsible for adding a new item for the list. We want it to have minimal responsibility, and **delegate the action to its parent component**. One of the advantages of this approach is that this component will be reusable, and can be attached to a different action in different situations.
But we don't want the todo-input component to be responsible for adding a new item for the list. We want it to have minimal responsibility, and **delegate the action to its parent component**. One of the advantages of this approach is that this component will be reusable, and can be attached to a different action in different situations.

For example, in our case, we'll be able to use the `inputComponent` inside the `itemComponent`. Then we'll have an input box for each item and we'll be able to edit the item's title. In this case, pressing the Enter key or the save button will have a different effect.

So what we actually want to do is to **emit an event** from the todo-input component whenever the title is changed. With Angular we can easily define and emit events from our components!

## @Output()
## @Output\(\)

Inside the `inputComponent` class add the following line, which defines an output for the component.

```ts
```typescript
@Output() submit: EventEmitter<string> = new EventEmitter();
```

The output property is called `submit`. Make sure that Output and EventEmitter are added to the import declaration in the first line of the file:
The output property is called `submit`. Make sure that Output and EventEmitter are added to the import declaration in the first line of the file:

```ts
```typescript
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
```

Now, whenever we call `this.submit.emit()` an event will be emitted to the parent component. Let's call it in the changeTitle method:

```ts
```typescript
changeTitle(newTitle: string): void {
this.submit.emit(newTitle);
}
Expand All @@ -38,13 +38,13 @@ Nothing else is changed in the todo-input component. The events emitted from `ke

Now all we need to do is catch the event in the parent component and attach logic to it. Go to the app-root component and bind to the `submit` event in the `<todo-input>` component:

```html
```markup
<todo-input (submit)="addItem($event)"></todo-input>
```

Now all that left is to implement the `addItem` method, which receives a string and adds it to the list:

```ts
```typescript
addItem(title: string): void {
this.todoList.push({ title });
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
# Add more abilities to service

# In this chapter we would improve our service by adding more abilities.
## Add more abilities to service

## In this chapter we would improve our service by adding more abilities.

First, lets open our app's service file which is available at - `app/todo-list.service.ts`

There we'll add a new function to the service, called `addItem`, like so:

```javascript
addItem(item): void {
this.todoList.push({ item });
}
}
```

This will allow us to call the same function from everywhere across the application thus making our app more easy to maintain.

And now we can change our code in `app/list-manager/list-manager.component.ts` to call the `addItem` function directly from the service like so:
And now we can change our code in `app/list-manager/list-manager.component.ts` to call the `addItem` function directly from the service like so:

```javascript
addItem(item): void {
this.todoListService.addItem(item);
}
}
```

- There may be additional logic when calling these methods, i.e. saving the changes in the DB (we will implement it later on)
- A better way to handle data is using immutable objects, then there will be no binding - the references will change (but we won’t implement redux in this tutorial at the moment)
* There may be additional logic when calling these methods, i.e. saving the changes in the DB \(we will implement it later on\)
* A better way to handle data is using immutable objects, then there will be no binding - the references will change \(but we won’t implement redux in this tutorial at the moment\)

23 changes: 13 additions & 10 deletions adding_a_checkbox.md → adding-a-checkbox.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Adding A Checkbox
# Adding a checkbox

We are now able to interact with our todo list by removing items. But what if we want to complete items and still be able to see them on our list, for example, have a line-strike through the todo title? Enter the checkbox!

Expand All @@ -11,35 +11,37 @@ We will look at:

Let's go ahead and add a checkbox into our item.component.ts file. Place the following code right before the `<p>` tag containing `{{ todoItem.title}}`:

```html
```markup
<input type="checkbox"/>
```
Now, in order for the checkbox to do anything we need to add a click event which we will call completeItem(). Let's do that now:

```html
Now, in order for the checkbox to do anything we need to add a click event which we will call completeItem\(\). Let's do that now:

```markup
<input type="checkbox" (click)="completeItem()"/>
```
When we click on the checkbox it will run the completeItem() function. Let's talk about what this function needs to accomplish. We want to be able to toggle some CSS styling on the todo title so that when the checkbox is checked it will have a line-strike through it, and no line-strike when unchecked. In order to achieve this we will toggle a variable to be either true or false to represent checked or unchecked states. Add the following code to the ItemComponent class:

```js
When we click on the checkbox it will run the completeItem\(\) function. Let's talk about what this function needs to accomplish. We want to be able to toggle some CSS styling on the todo title so that when the checkbox is checked it will have a line-strike through it, and no line-strike when unchecked. In order to achieve this we will toggle a variable to be either true or false to represent checked or unchecked states. Add the following code to the ItemComponent class:

```javascript
isComplete: boolean = false;

completeItem() {
this.isComplete = !this.isComplete;
}
```

But wait! How is any of this going to affect the todo title when we're only touching the checkbox??? Well, Angular2 has this wonderful directive called NgClass. This directive applies or removes a class based on a boolean value (true or false). There are many ways to use this directive(see documentation: https://angular.io/docs/ts/latest/api/common/index/NgClass-directive.html) but we will focus on using it like so:
But wait! How is any of this going to affect the todo title when we're only touching the checkbox??? Well, Angular2 has this wonderful directive called NgClass. This directive applies or removes a class based on a boolean value \(true or false\). There are many ways to use this directive\(see documentation: [https://angular.io/docs/ts/latest/api/common/index/NgClass-directive.html](https://angular.io/docs/ts/latest/api/common/index/NgClass-directive.html)\) but we will focus on using it like so:

```html
```markup
<some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
```

The 'first' and 'second' class will be applied to the element because they are given a true value, whereas, the 'third' class will not be applied because it is given a false value. So this is where our earlier code comes into play. Our completeItem() function will toggle between true and false values, thus dictating whether a class should be applied or removed.
The 'first' and 'second' class will be applied to the element because they are given a true value, whereas, the 'third' class will not be applied because it is given a false value. So this is where our earlier code comes into play. Our completeItem\(\) function will toggle between true and false values, thus dictating whether a class should be applied or removed.

Let's add this NgClass directive to our todo title now:

```html
```markup
<p class="todo-title" [ngClass]="{'todo-complete': isComplete}">
{{ todoItem.title }}
</p>
Expand All @@ -54,3 +56,4 @@ And finally, add the css to our item.component.css file
```

Voila! Checking the checkbox should apply a line through the todo title, and unchecking the checkbox should remove the line.

Loading