├── class ├── 1-introduction │ ├── 02.1-RIA-Conceitos.pdf │ ├── 01-first-meeting.md │ └── 02-applications-with-rich-interfaces.md ├── 2-development-environment-setup │ ├── 05-unit-test.md │ ├── 03-version-control.md │ ├── 07-typescript.md │ ├── 06-pipeline.md │ └── 04-devcontainer.md └── 4-angular │ ├── 17-backend-communication.md │ ├── 14-services.md │ ├── 12-ui-components.md │ ├── 08-basics.md │ ├── 09-create-project.md │ ├── 10-data-binding.md │ ├── 18-http-client.md │ ├── 13-components.md │ ├── 15-routers.md │ ├── 11-directives.md │ └── 16-forms.md ├── objectives.md ├── communication.md ├── README.md ├── assessment.md ├── classes.md ├── .gitignore ├── contents.md └── LICENSE /class/1-introduction/02.1-RIA-Conceitos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/persapiens-classes/ifrn-ria/HEAD/class/1-introduction/02.1-RIA-Conceitos.pdf -------------------------------------------------------------------------------- /class/1-introduction/01-first-meeting.md: -------------------------------------------------------------------------------- 1 | :wave: First Meeting - Overall Syllabus Explanation 2 | ==== 3 | 4 | 1. [Objectives](../../objectives.md) 5 | 2. [Contents](../../contents.md) 6 | 3. [Communication](../../communication.md) 7 | 4. [Assessment](../../assessment.md) 8 | 5. [Classes](../../classes.md) -------------------------------------------------------------------------------- /objectives.md: -------------------------------------------------------------------------------- 1 | Objectives 2 | ==== 3 | 4 | See description of course **[Aplicações com Interfaces Ricas (Page 111)](https://portal.ifrn.edu.br/documents/739/PPC__Tecnologia_em_An%C3%A1lise_e_Desenvolvimento_de_Sistemas_2012.pdf)** 5 | 6 | - Understand the rich interface development environment. 7 | - Develop applications with rich interface. -------------------------------------------------------------------------------- /class/1-introduction/02-applications-with-rich-interfaces.md: -------------------------------------------------------------------------------- 1 | Applications with Rich Interfaces 2 | ==== 3 | 4 | [👍 Ria Concepts](02.1-RIA-Conceitos.pdf) 5 | 6 | [👍 Frontend Developer Roadmap](https://roadmap.sh/frontend?authuser=3) 7 | 8 | :trophy: This class was donated by [Professor Alessandro Sousa](https://github.com/alessandrojsouza). Thank you very much. 🚀🚀🚀 -------------------------------------------------------------------------------- /communication.md: -------------------------------------------------------------------------------- 1 | Communication 2 | ==== 3 | 4 | - News at [Google Classroom Mural](https://classroom.google.com/u/3/c/NzIyOTcwNTI5ODY3) 5 | 6 | - Tasks at [Google Classroom Atividades](https://classroom.google.com/u/3/c/NzIyOTcwNTI5ODY3/t/all) 7 | 8 | - Grades [Suap](https://suap.ifrn.edu.br) 9 | 10 | - Support at [Google Classroom Mural](https://classroom.google.com/u/3/c/NzIyOTcwNTI5ODY3) and at Personal (DIATINF / IFRN). 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Applications with Rich Interfaces Discipline 2 | ==== 3 | 4 | The sections [Objectives](#objectives) and [Contents](#contents) is derived from the course **[Aplicações com Interfaces Ricas (Page 111)](https://portal.ifrn.edu.br/documents/739/PPC__Tecnologia_em_An%C3%A1lise_e_Desenvolvimento_de_Sistemas_2012.pdf)** of Course [Tecnologia em Análise e Desenvolvimento de Sistemas - TADS](https://portal.ifrn.edu.br/cursos/superiores/graduacao/tecnologia-em-analise-e-desenvolvimento-de-sistemas/) from [DIATINF Natal Central](https://diatinf.ifrn.edu.br/), [Instituto Federal do Rio Grande do Norte - IFRN](https://ifrn.edu.br). 5 | 6 | ## Instructor 7 | - Professor Marcelo Romulo Fernandes - marcelo.fernandes@ifrn.edu.br 8 | 9 | ## [Classes](classes.md) 10 | 11 | ## [Objectives](objectives.md) 12 | 13 | ## [Assessment](assessment.md) 14 | 15 | ## [Communication](communication.md) 16 | 17 | ## [Contents](contents.md) 18 | -------------------------------------------------------------------------------- /class/2-development-environment-setup/05-unit-test.md: -------------------------------------------------------------------------------- 1 | Unit Test 2 | ==== 3 | 4 | > [**Unit testing** Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually scrutinized for proper operation. Software developers and sometimes QA staff complete unit tests during the development process.](https://www.techtarget.com/searchsoftwarequality/definition/unit-testing) 5 | 6 | ## :star: Hands on with [RIA Example Project.](https://github.com/persapiens-classes/ifrn-ria-example/issues/8) 7 | 8 | ## :construction_worker: Task 9 | 10 | Create one pull request for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 11 | 12 | Implement **factorial math function** function. 13 | 14 | Implement unit tests for **factorial math function** function. 15 | 16 | Run the unit tests with pipeline. 17 | 18 | Create a **separate commit** to each duplicated code fixed. 19 | -------------------------------------------------------------------------------- /assessment.md: -------------------------------------------------------------------------------- 1 | Assessment 2 | ==== 3 | 4 | - [Work with pais.](https://au.indeed.com/career-advice/interviewing/how-do-you-ensure-you-work-well-in-a-team) 5 | 6 | - Work with projects. 7 | 8 | - Continuous assessment. Weekly. All practical tasks. 9 | 10 | - Some challenges. 11 | 12 | - Grade is the average of the bimester's tasks grades. 13 | 14 | - Individual grade. 15 | 16 | - Final test with a traditional theoretical exam. 17 | 18 | ## Task Submission 19 | 20 | - Use the technology stack (programming language, framework) indicated by your professor. 21 | 22 | - [Version controlled](class/2-development-environment-setup/03-version-control.md): branch, commits and pull requests. 23 | 24 | - Issue, branch, pull request and commits should be connected. 25 | 26 | - [Unit Tests](class/2-development-environment-setup/05-unit-tests.md) should run ok. 27 | 28 | - [Pipeline](class/2-development-environment-setup/06-pipeline.md) should build ok including with tests. 29 | 30 | - Explain the submission to the professor. 31 | -------------------------------------------------------------------------------- /class/2-development-environment-setup/03-version-control.md: -------------------------------------------------------------------------------- 1 | :wave: Version Control 2 | ==== 3 | 4 | - Version controlled using [Github Flow.](https://medium.com/@patrickporto/4-branching-workflows-for-git-30d0aaee7bf) 5 | 6 | - Create an issue to describe the task. 7 | 8 | - [Create a branch to work on the issue.](https://docs.github.com/en/issues/tracking-your-work-with-issues/creating-a-branch-for-an-issue) 9 | 10 | - [Use Semantic Commit messages.](https://gist.github.com/joshbuchea/6f47e86d2510bce28f8e7f42ae84c716) 11 | 12 | - [Good commit messages are appreciated.](https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/) 13 | 14 | - [Version controlled using pull requests.](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request) 15 | 16 | - Version Control Repository: GitHub 17 | 18 | 19 | ## 👷 Task 20 | 21 | Create one issue for your project. It should do something valuable to your project. 22 | 23 | Associate one branch for the issue. 24 | 25 | Do some commits in the branch. 26 | 27 | When you finish the implementation in the branch, create a PR from your branch. 28 | 29 | Merge the PR into the main branch. 30 | 31 | Examples: [Adding README](https://github.com/persapiens-classes/ifrn-ria-example/issues/1), Introducing team definition, Fixing typos, Fixing some open issues. 32 | -------------------------------------------------------------------------------- /class/2-development-environment-setup/07-typescript.md: -------------------------------------------------------------------------------- 1 | TypeScript 2 | ==== 3 | 4 | ## :hammer: Definition 5 | 6 | [TypeScript is JavaScript with syntax for types. TypeScript is a strongly typed programming language that builds on JavaScript, giving you better tooling at any scale.](https://www.typescriptlang.org/) 7 | 8 | Let's explore the [differences between TypeScript and JavaScript](https://www.geeksforgeeks.org/difference-between-typescript-and-javascript/). 9 | 10 | ### TypeScript Resources 11 | 12 | - [TypeScript Github Repository](https://github.com/microsoft/TypeScript) 13 | - [Get Started and Handbook sections of TypeScript Documentation](https://www.typescriptlang.org/docs/) 14 | - [TypeScript PlayGround](https://www.typescriptlang.org/play) 15 | - [JavaScript Mozilla Tutorial](https://developer.mozilla.org/docs/Web/JavaScript) 16 | 17 | ### TypeScript Setup 18 | 19 | Use the [tutorial](https://blog.lsantos.dev/jest-com-typescript/) to configure typescript, including tests with jest. 20 | 21 | Hands on with [RIA Example Project.](https://github.com/persapiens-classes/ifrn-ria-example/issues/18) 22 | 23 | ## :construction_worker: Task 24 | 25 | Create one pull request for your project according to [Task Submission Guidelines.](../../assessment.md#task-submission) 26 | 27 | Configure typescript like hands-on above. 28 | Reimplement fatorial function with typescript types. 29 | 30 | Run the action with unit tests successfully. 31 | -------------------------------------------------------------------------------- /class/2-development-environment-setup/06-pipeline.md: -------------------------------------------------------------------------------- 1 | CI/CD Pipeline 2 | ==== 3 | 4 | ## :hammer: Lean Management 5 | 6 | [Inspired by Toyota’s production system, Lean Management is a management and work organisation method aimed at improving a company’s performance and, more specifically, the quality and profitability of its output.](https://www.manutan.com/blog/en/glossary/lean-management-definition-and-tools) 7 | 8 | See lean in action in this [video](https://www.youtube.com/watch?v=wfsRAZUnonI) 9 | 10 | 11 | ## :bulb: Definition 12 | 13 | According to [Semaphoreci](https://semaphoreci.com/blog/cicd-pipeline) 14 | 15 | > A CI/CD pipeline automates your software delivery process. The pipeline builds code, runs tests (CI), and safely deploys a new version of the application (CD). 16 | > Automated pipelines remove manual errors, provide standardized feedback loops to developers, and enable fast product iterations. 17 | 18 | 19 | ### Github Actions 20 | 21 | Let's use [Github Actions](https://docs.github.com/en/actions) to create a build pipeline of our project. 22 | 23 | Hands on with [RIA Example Project.](https://github.com/persapiens-classes/ifrn-ria-example/issues/15) 24 | 25 | ## :construction_worker: Task 26 | 27 | Create one pull request for your project according to [Task Submission Guidelines.](../../assessment.md#task-submission) 28 | 29 | Create a github action workflow to build your project. 30 | 31 | Run the action successfully. 32 | -------------------------------------------------------------------------------- /classes.md: -------------------------------------------------------------------------------- 1 | Classes 2 | ==== 3 | 4 | ### Introduction 5 | 6 | 1. [First Meeting](class/1-introduction/01-first-meeting.md) 7 | 8 | 2. [Applications with Rich Interfaces](class/1-introduction/02-applications-with-rich-interfaces.md) 9 | 10 | ### Development Environment Setup 11 | 12 | 3. [Version Control](class/2-development-environment-setup/03-version-control.md) 13 | 14 | 4. [Visual Code Dev Container and Github Codespaces](class/2-development-environment-setup/04-devcontainer.md) 15 | 16 | 5. [Unit Test](class/2-development-environment-setup/05-unit-test.md) 17 | 18 | 6. [CI/CD Pipeline](class/2-development-environment-setup/06-pipeline.md) 19 | 20 | 7. [TypeScript Setup](class/2-development-environment-setup/07-typescript.md) 21 | 22 | ### TypeScript 23 | 24 | ### Angular 25 | 26 | 8. [Basics](class/4-angular/08-basics.md) 27 | 28 | 9. [Create Project](class/4-angular/09-create-project.md) 29 | 30 | 10. [Data Binding](class/4-angular/10-data-binding.md) 31 | 32 | 11. [Directive](class/4-angular/11-directives.md) 33 | 34 | 12. [UI Components with PrimeNg](class/4-angular/12-ui-components.md) 35 | 36 | 13. [Components](class/4-angular/13-components.md) 37 | 38 | 14. [Service](class/4-angular/14-services.md) 39 | 40 | 15. [Routers](class/4-angular/15-routers.md) 41 | 42 | 16. [Forms](class/4-angular/16-forms.md) 43 | 44 | 17. [Backend Communication](class/4-angular/17-backend-communication.md) 45 | 46 | 18. [HttpClient](class/4-angular/18-http-client.md) 47 | 48 | 19. [State Management] 49 | 50 | :trophy: This angular classes was initially donated by [Professor Alessandro Sousa](https://github.com/alessandrojsouza). Thank you very much. 🚀🚀🚀 51 | -------------------------------------------------------------------------------- /class/2-development-environment-setup/04-devcontainer.md: -------------------------------------------------------------------------------- 1 | :wave: Developing inside a Container 2 | ==== 3 | 4 | [The Visual Studio Code Dev Containers extension lets you use a container as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set.](https://code.visualstudio.com/docs/devcontainers/containers) 5 | 6 | :heart: Why you should use Dev Containers? 7 | - Ease of onboarding new developers 8 | - Use of consistent tools 9 | - Standardization of versions 10 | - Reduce system conflicts 11 | - Improve task startup time 12 | 13 | :unlock: System Requirements: 14 | - [Docker](https://docker.com) 15 | - [Visual Code](https://code.visualstudio.com/) 16 | - Dev Containers Visual Code Extension 17 | 18 | :star: Nice Tutorials: 19 | - [Developing inside a Container](https://code.visualstudio.com/docs/devcontainers/containers) 20 | - [Treinamento Dev Container by Professor Alessando](https://fabulous-chess-d6a.notion.site/Treinamento-Dev-Container-f0d3d608583a4c8391f9383716455226) 21 | 22 | :key: devcontainer.json 23 | - Main file in a development container configuration. 24 | - Instructs the development container on framework, tools, extensions, and port forwarding. 25 | 26 | ## 👷 Task 27 | 28 | - Create one pull request for your project according to [Task Submission Guidelines.](../../assessment.md#task-submission) 29 | 30 | - Create a devcontainer.json to configure a dev container for your project. See the [example](https://github.com/persapiens-classes/ifrn-ria-example/issues/3). 31 | 32 | - Start the dev container successfully. 33 | 34 | 35 | :trophy: This class was donated by [Professor Alessandro Sousa](https://github.com/alessandrojsouza). Thank you very much. 🚀🚀🚀 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* 131 | -------------------------------------------------------------------------------- /class/4-angular/17-backend-communication.md: -------------------------------------------------------------------------------- 1 | ## Backend Communication 2 | 3 | 4 | ### Rest API Protocol 5 | 6 | [REpresentational State Transfer (REST) is an architectural style that defines a set of constraints to be used for creating web services. REST API is a way of accessing web services in a simple and flexible way without having any processing.](https://www.geeksforgeeks.org/rest-api-introduction/) 7 | 8 | [In HTTP there are five methods that are commonly used in a REST-based Architecture i.e., POST, GET, PUT, PATCH, and DELETE. These correspond to create, read, update, and delete (or CRUD) operations respectively. There are other methods which are less frequently used like OPTIONS and HEAD.](https://www.geeksforgeeks.org/rest-api-introduction/) 9 | 10 | 11 | ### JSON 12 | 13 | [JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999.](https://www.json.org/json-en.html) 14 | 15 | 16 | ### JWT Authentication 17 | 18 | [JSON Web Token, commonly referred to as JWT, is an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. The token is digitally signed, ensuring its authenticity and integrity. JWTs are primarily used to authenticate users, authorize access to certain resources, and exchange information securely.](https://medium.com/@extio/understanding-json-web-tokens-jwt-a-secure-approach-to-web-authentication-f551e8d66deb) 19 | 20 | 21 | ### CORS (Be careful if Backend and Angular Frontend running in different hosts) 22 | 23 | [Cross-origin resource sharing (CORS) is a mechanism to safely bypass the same-origin policy, that is, it allows a web page to access restricted resources from a server on a domain different than the domain that served the web page.](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 24 | 25 | [A web page may freely embed cross-origin images, stylesheets, scripts, iframes, and videos. Certain "cross-domain" requests, notably Ajax requests, are forbidden by default by the same-origin security policy. CORS defines a way in which a browser and server can interact to determine whether it is safe to allow the cross-origin request. It allows for more freedom and functionality than purely same-origin requests, but is more secure than simply allowing all cross-origin requests.](https://en.wikipedia.org/wiki/Cross-origin_resource_sharing) 26 | 27 | See [Cors Configuration on Account Backend](https://github.com/persapiens-classes/account-backend/pull/170/files) 28 | 29 | 30 | ### HTTPS (Be careful if Backend and Angular Frontend running in different hosts) 31 | 32 | [Hypertext Transfer Protocol Secure (HTTPS) is an extension of the Hypertext Transfer Protocol (HTTP). It uses encryption for secure communication over a computer network, and is widely used on the Internet. In HTTPS, the communication protocol is encrypted using Transport Layer Security (TLS) or, formerly, Secure Sockets Layer (SSL). The protocol is therefore also referred to as HTTP over TLS, or HTTP over SSL.](https://en.wikipedia.org/wiki/HTTPS) 33 | -------------------------------------------------------------------------------- /class/4-angular/14-services.md: -------------------------------------------------------------------------------- 1 | ### **Angular Services** 2 | 3 | Services play a fundamental role in Angular's architecture, enabling the sharing of logic, data, and functionality between components in an efficient and organized manner. They are classes that can be injected into components, modules, and other services, promoting code reuse and separation of concerns. 4 | 5 | --- 6 | 7 | ### **Creating a Service** 8 | 9 | To create a new service, you can use the Angular CLI with the following command: 10 | 11 | ```bash 12 | ng generate service service-name 13 | ``` 14 | 15 | **Example of a Service:** 16 | 17 | ```typescript 18 | import { Injectable } from '@angular/core'; 19 | 20 | @Injectable({ 21 | providedIn: 'root', // Indicates that the service will be injected at the root level (singleton). 22 | }) 23 | export class MyService { 24 | data: string[] = []; 25 | 26 | addData(data: string) { 27 | this.data.push(data); 28 | } 29 | 30 | getData(): string[] { 31 | return this.data; 32 | } 33 | } 34 | ``` 35 | 36 | --- 37 | 38 | ### **Injecting a Service** 39 | 40 | Services can be injected into components, modules, or other services using Angular's dependency injection mechanism. 41 | 42 | **Example of Service Injection in a Component:** 43 | 44 | ```typescript 45 | import { Component } from '@angular/core'; 46 | import { MyService } from './my-service.service'; 47 | 48 | @Component({ 49 | selector: 'app-example', 50 | template: '', 51 | }) 52 | export class ExampleComponent { 53 | constructor(private myService: MyService) {} 54 | 55 | add() { 56 | this.myService.addData('New data'); 57 | } 58 | } 59 | ``` 60 | 61 | --- 62 | 63 | ### **Using Services to Share Data** 64 | 65 | Services are excellent for sharing data and state between components. They act as intermediaries, allowing one component to update the data and notifying other components of these changes. 66 | 67 | **Example of Using a Service to Share Data:** 68 | 69 | ```typescript 70 | import { Injectable } from '@angular/core'; 71 | import { BehaviorSubject } from 'rxjs'; 72 | 73 | @Injectable({ 74 | providedIn: 'root', 75 | }) 76 | export class SharedDataService { 77 | private dataSubject = new BehaviorSubject(''); 78 | 79 | updateData(data: string) { 80 | this.dataSubject.next(data); 81 | } 82 | 83 | getData() { 84 | return this.dataSubject.asObservable(); 85 | } 86 | } 87 | ``` 88 | 89 | --- 90 | 91 | ### **Summary** 92 | 93 | Services play a crucial role in Angular application development, enabling code reuse, separation of concerns, and efficient sharing of data and functionality between components. By creating and using services appropriately, you can develop a more modular, flexible, and scalable application architecture. 94 | 95 | ## 👷 Task 96 | 97 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 98 | 99 | - Create services for your models and refactor the crud component of the project in the previous task (13 components) to use it. 100 | 101 | You can use task [Create owner service](https://github.com/persapiens-classes/account-frontend/issues/12) of the Angular Example Project. 102 | -------------------------------------------------------------------------------- /contents.md: -------------------------------------------------------------------------------- 1 | Contents 2 | ==== 3 | 4 | See description of course **[Aplicações com Interfaces Ricas (Page 110)](https://portal.ifrn.edu.br/documents/739/PPC__Tecnologia_em_An%C3%A1lise_e_Desenvolvimento_de_Sistemas_2012.pdf)** 5 | 6 | 1. Introduction 7 | 1. Some rich interface features 8 | 1. Development environment 9 | 10 | 2. Basic concepts 11 | 1. Element and attributes 12 | 2. Element and properties 13 | 3. Events 14 | 4. Type converters 15 | 16 | 3. Layout 17 | 1. Rendering process 18 | 2. Virtual dashboards 19 | 3. Custom dashboards 20 | 21 | 4. Controls 22 | 1. Hierarchy of controls 23 | 2. Content controls, Items controls, Range Controls, etc. 24 | 3. Positioning, size and transformations 25 | 3.1. Size of elements 26 | 3.2. Margins and spacing 27 | 3.3. Alignments 28 | 3.4. Transformations 29 | 30 | 5. Resources 31 | 1. Requirement for using objects as a resource 32 | 2. Resource dictionary fusion 33 | 3. Reference to other resources 34 | 4. Using resources from code 35 | 36 | 6. Customization of Controls 37 | 1. Inline styles 38 | 2. Style Object 39 | 3. Style inheritance 40 | 4. Themes 41 | 4.1. Implicit application of themes 42 | 4.2. Using the Theme control 43 | 5. Templates 44 | 5.1. Basic interface definition 45 | 5.2. Using the basic interface 46 | 6. Custom controls 47 | 6.1. Basic interface definition 48 | 6.2. Use of parts 49 | 6.3. Propagation of styles 50 | 6.4. State usage 51 | 6.5. Adding properties 52 | 53 | 7. Data Connection 54 | 1. Introduction to data binding 55 | 2. Data connection usage 56 | 3. Data binding between visual controls 57 | 4. Converters 58 | 5. Using contexts 59 | 6. Data validation 60 | 7. Collections 61 | 62 | 8. Animations 63 | 1. Introduction to animations 64 | 2. Targeting an animation 65 | 3. Easing Functions 66 | 4. Animations with Keyframes 67 | 5. Frame-by-frame animations 68 | 6. Graphics tools 69 | 70 | 9. Average 71 | 1. Supported formats 72 | 2. MediaElement element 73 | 2.1. Volume and balance 74 | 2.2. States of a MediaPlay element 75 | 2.3. Buffering 76 | 2.4. Events 77 | 2.5. Video playback 78 | 2.6. Progressive Download VS Streaming 79 | 2.7. Using markers 80 | 2.8. Building a player 81 | 2.9. Digital Rights Management (DRM) 82 | 3. VideoBrush 83 | 4. Interaction with webcam and microphone 84 | 85 | 10. Other Services 86 | 1. Print 87 | 1.1. Simple printing of a form 88 | 1.2. Personalization of the printed document 89 | 1.3. Document pagination 90 | 1.4. Printing feedback 91 | 2. Custom context menu 92 | 3. Clipboard Access 93 | 4. Navigation between pages 94 | 4.1. Navigation options 95 | 4.2. Navigation events 96 | 4.3. Sending data to pages 97 | 4.4. Browsing history 98 | 4.5. Customization of the navigation system 99 | 100 | 11. Security 101 | 1. Security models 102 | 2. Security levels 103 | 3. Security attributes 104 | 4. Cross-site scripting 105 | 5. Control communication between pugin and host 106 | 6. Security when accessing network resources 107 | 7. User data security -------------------------------------------------------------------------------- /class/4-angular/12-ui-components.md: -------------------------------------------------------------------------------- 1 | ## Angular UI Components 2 | 3 | There are several visual component libraries that can be used in Angular projects to facilitate the development of more sophisticated and responsive user interfaces (UI). Some of the most popular libraries include: 4 | 5 | ### 1. **Angular Material** 6 | - **Description**: Angular Material is a component library developed by the Angular team, based on Material Design. It provides a collection of ready-to-use components such as buttons, tables, forms, menus, etc. 7 | - **Website**: [https://material.angular.io](https://material.angular.io) 8 | 9 | ### 2. **NG Bootstrap** 10 | - **Description**: NG Bootstrap provides Bootstrap-based UI components but without relying on jQuery or additional JavaScript. It is a modern alternative to Bootstrap for Angular projects. 11 | - **Website**: [https://ng-bootstrap.github.io](https://ng-bootstrap.github.io) 12 | 13 | ### 3. **PrimeNG** 14 | - **Description**: PrimeNG is a rich UI library with a wide range of components for Angular, such as tables, charts, calendars, menus, and more. It is known for its versatility and the large number of available components. 15 | - **Website**: [https://primeng.org/](https://primeng.org/) 16 | 17 | ### 4. **Clarity Design System** 18 | - **Description**: Clarity is a UI component library and design system developed by VMware. It offers a collection of components based on a design system, with a focus on user experience and accessibility. 19 | - **Website**: [https://clarity.design](https://clarity.design) 20 | 21 | ### 5. **Kendo UI for Angular** 22 | - **Description**: Kendo UI is a rich component library with a wide range of widgets and components, focused on performance and customization. 23 | - **Website**: [https://www.telerik.com/kendo-angular-ui](https://www.telerik.com/kendo-angular-ui) 24 | 25 | ### 6. **ngx-bootstrap** 26 | - **Description**: ngx-bootstrap is a Bootstrap component library specifically for Angular, with no jQuery dependencies. It provides many of the Bootstrap components, such as modals, popovers, and tooltips. 27 | - **Website**: [https://valor-software.com/ngx-bootstrap/](https://valor-software.com/ngx-bootstrap/) 28 | 29 | ### 7. **Nebular** 30 | - **Description**: Nebular is a UI component library offering a collection of highly customizable components, with a focus on design and usability. It is ideal for dashboards and enterprise applications. 31 | - **Website**: [https://akveo.github.io/nebular/](https://akveo.github.io/nebular/) 32 | 33 | ### 8. **Ant Design for Angular (ng-zorro-antd)** 34 | - **Description**: ng-zorro-antd is an Angular component library that implements Ant Design, a popular design system. It offers rich, modern components for building user interfaces. 35 | - **Website**: [https://ng.ant.design](https://ng.ant.design) 36 | 37 | These libraries help accelerate the development of rich, interactive interfaces in Angular by providing ready-made and customizable components. The choice of which one to use depends on the needs of your project and design preferences. 38 | 39 | 40 | ## Install PrimeNg 41 | 42 | [PrimeNg](https://primeng.org) is a comprehensive suite of customizable, feature-rich UI components. 43 | 44 | Follow the steps [Download](https://primeng.org/installation#download) and [Provider](https://primeng.org/installation#provider) described in [PrimeNg Getting Started Installation](https://primeng.org/installation). 45 | 46 | Optionally, [install Prime Icons](https://primeng.org/icons). 47 | 48 | ## 👷 Task 49 | 50 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 51 | 52 | - Create an angular project in Github repository. 53 | - Choose and include an Angular UI Component Library to your project. 54 | - Create insert, update, detail, remove, and list operations of a model using UI components in your app component. 55 | - Your model should have 3 at least attributes: string, number, and boolean. 56 | 57 | You can use [Task: Create insert and list of names with primeng](https://github.com/persapiens-classes/account-frontend/issues/6) of Angular Example Project. 58 | -------------------------------------------------------------------------------- /class/4-angular/08-basics.md: -------------------------------------------------------------------------------- 1 | # Fundamentals of the Angular Framework 2 | 3 | ## What is Angular? 4 | 5 | Angular is a framework for building client applications using HTML, CSS, and JavaScript/TypeScript. It employs the SPA (**_Single Page Application_**) approach, enabling the application to load once and dynamically update content without reloading the page. 6 | 7 | ## Why use Angular? 8 | 9 | - **Productivity**: Angular provides tools and frameworks that facilitate agile and efficient development. 10 | - **Solid Architecture**: Its modular, component-oriented design simplifies code organization and functionality reuse. 11 | - **Performance**: Angular optimizes application performance, ensuring a fast and fluid user experience. 12 | - **Ecosystem and Active Community**: The Angular platform has a large developer community and numerous libraries and resources available. 13 | 14 | ## Key Features and Benefits 15 | 16 | - **TypeScript**: Angular is written in TypeScript, which adds static typing to JavaScript, making the code more robust and readable. 17 | - **Data Binding**: The powerful data binding mechanism synchronizes data between components and templates easily. 18 | - **Dependency Injection**: Angular’s dependency injection system efficiently manages dependencies between components. 19 | - **Directives**: Directives extend HTML syntax, enabling custom behaviors for page elements. 20 | - **Routing**: Angular's router facilitates multi-page applications within an SPA, managing transitions between components. 21 | - **Testability**: Angular encourages testing practices, making applications more reliable and maintainable. 22 | 23 | ## Angular Architecture 24 | 25 | Angular's architecture is based on fundamental concepts such as **_components_**, **_modules_**, **_services_**, and **_directives_**. Combine these elements to create a solid and modular structure for developing efficient and scalable web applications. 26 | 27 | 1. **Components**: 28 | 29 | Components are the building blocks of Angular. They control specific parts of the user interface and can be reused throughout the application. Each component has an associated template defining the DOM structure to be rendered. 30 | 31 | Angular component example: 32 | 33 | ```typescript 34 | import { Component } from '@angular/core'; 35 | 36 | @Component({ 37 | selector: 'app-example', // Component selector used in templates 38 | templateUrl: './example.component.html', // Path to the component's template 39 | styleUrls: ['./example.component.scss'], // Associated style files 40 | }) 41 | export class ExampleComponent { 42 | // Component logic here... 43 | } 44 | ``` 45 | 46 | 47 | 2. **Templates**: 48 | Templates are a vital part of Angular's architecture. They define the DOM structure to be rendered for a specific component. Templates are written in HTML and can include directives and bindings to display data and interact with the component's logic. 49 | 50 | Example of an Angular template: 51 | 52 | ```html 53 |

Item List

54 | 57 | ``` 58 | 59 | 60 | 3. **Directives**: 61 | Directives are instructions for the DOM. They can be used to modify the appearance, behavior, or structure of HTML. There are built-in directives such as **if** and **for**, and you can also create your own custom directives. 62 | 63 | Example of using directive @if in templates: 64 | 65 | ```typescript 66 | @if (condicao) { 67 | 68 | } @else if (b > a) { 69 | {{a}} is less than {{b}} 70 | } @else { 71 | {{a}} is equal to {{b}} 72 | } 73 | ``` 74 | 75 | 76 | 4. **Services**: 77 | Services are classes that contain reusable logic and can be injected into components and other services. They are used to share data, make HTTP calls, perform asynchronous operations, and much more. 78 | 79 | Example of an Angular service: 80 | 81 | ```typescript 82 | import { Injectable } from '@angular/core'; 83 | 84 | @Injectable({ 85 | providedIn: 'root', // Configuration to make the service available throughout the application. 86 | }) 87 | export class ExampleService { 88 | items: string[] = []; 89 | 90 | adicionarDado(item: string) { 91 | this.items.push(item); 92 | } 93 | 94 | getItems(): string[] { 95 | return this.items; 96 | } 97 | } 98 | ``` 99 | 100 | 101 | 5. **Modules**: 102 | Modules are used to organize code into functional and independent pieces. Every Angular application has at least one root module (usually called AppModule) that is responsible for initializing the application. Additionally, you can create modules to organize specific functionalities. 103 | 104 | Example of an Angular module: 105 | 106 | ```typescript 107 | import { NgModule } from '@angular/core'; 108 | import { CommonModule } from '@angular/common'; 109 | import { ExampleComponent } from './example.component'; 110 | 111 | @NgModule({ 112 | declarations: [ExampleComponent], // Components declared in this module. 113 | imports: [CommonModule], // Modules imported for use in this module. 114 | exports: [ExampleComponent], // Components, directives, and pipes available to other modules. 115 | }) 116 | export class ExampleModule { } 117 | 118 | ``` 119 | 120 | 121 | -------------------------------------------------------------------------------- /class/4-angular/09-create-project.md: -------------------------------------------------------------------------------- 1 | # Create Angular project with PrimeNg 2 | 3 | ## Installing Angular CLI 4 | 5 | Before we start creating an Angular project, let's install Angular CLI, a command-line interface that simplifies Angular application development. 6 | 7 | 1. Open your terminal or command prompt. 8 | 9 | 2. Run the following command to install Angular CLI globally on your system: 10 | 11 | ```bash 12 | npm install -g @angular/cli 13 | ``` 14 | 15 | ## Creating a New Angular Project 16 | 17 | Now that we have Angular CLI installed, let's create a new Angular project. 18 | 19 | Choose the directory where you want to create the project and navigate to it in the terminal. 20 | 21 | Run the following command to create a new Angular project: 22 | 23 | ```bash 24 | ng new project-name 25 | ``` 26 | 27 | The Angular CLI will ask some questions about the project configuration. You can choose to configure them according to your needs or simply press "Enter" to use the default settings. 28 | 29 | Wait until the creation process is completed. The Angular CLI will create the basic project structure and install the necessary dependencies. 30 | 31 | Navigate to the directory of the newly created project: 32 | 33 | ```bash 34 | cd project-name 35 | ``` 36 | 37 | Now, you can start the development server to run the project: 38 | 39 | ```bash 40 | ng serve 41 | ``` 42 | 43 | If you are running a **devcontainer inside Linux**, you should run the project with the following options: 44 | 45 | ```bash 46 | ng serve --host 0.0.0.0 --port 4200 47 | ``` 48 | 49 | If you are running a **devcontainer inside Windows**, you should run the project with the following options: 50 | 51 | ```bash 52 | ng serve --host 0.0.0.0 --port 4200 --poll 2000 53 | ``` 54 | 55 | Open your browser and visit http://localhost:4200/. 56 | You should see the Angular application running. 57 | 58 | ## Project Structure 59 | 60 | ``` 61 | project-name/ 62 | |- e2e/ 63 | |- node_modules/ 64 | |- src/ 65 | | |- app/ 66 | | | |- components/ 67 | | | |- services/ 68 | | | |- app.module.ts 69 | | | |- app.component.ts 70 | | | |- app.component.html 71 | | | |- app.component.scss 72 | | | |- app.component.spec.ts 73 | | |- assets/ 74 | | |- environments/ 75 | | |- index.html 76 | | |- main.ts 77 | | |- styles.scss 78 | |- angular.json 79 | |- package.json 80 | |- tsconfig.json 81 | |- ... 82 | ``` 83 | 84 | ## Project Structure 85 | 86 | This is the basic structure of an Angular project. As you develop the application, other directories and files might be created to accommodate new components, services, modules, and so on. It's important to follow this organization to maintain a clean and well-structured Angular project, facilitating collaboration and maintenance. 87 | 88 | **Explanation of the Structure**: 89 | 90 | - **_e2e/_**: The _"e2e"_ directory contains end-to-end (e2e) tests written using the Protractor testing tool. These tests simulate user actions and verify if the application works correctly in an environment similar to production. 91 | 92 | - **_node_modules/_**: This is the directory where all npm package dependencies are installed. It is created automatically when you run `npm install` to download the project's dependencies. 93 | 94 | - **_src/_**: This is the main directory where the source code of the Angular application is located. 95 | 96 | - **_src/app/_**: The _"app"_ directory contains all components, services, and files related to the application's logic. 97 | 98 | - **_src/app/components/_**: In this directory, you can organize your components into subdirectories or create individual components. Each component consists of four files: _.component.ts_, _.component.html_, _.component.css_, and _.component.spec.ts_. 99 | 100 | - **_src/app/services/_**: In this directory, you can create and organize services used to share data and logic between components. 101 | 102 | - **_src/app/app.module.ts_**: The _"app.module.ts"_ file is the root module of the application. It imports and declares the components, services, and other modules used by the application. 103 | 104 | - **_src/app/app.component.ts_**: The _"app.component.ts"_ file is the root component of the application, which controls the main template _"app.component.html"_ and the stylesheet _"app.component.css"_. 105 | 106 | - **_src/app/app.component.html_**: The _"app.component.html"_ file is the main template of the application, defining the DOM structure that will be rendered. 107 | 108 | - **_src/app/app.component.css_**: The _"app.component.css"_ file contains styles specific to the root component. 109 | 110 | - **_src/app/app.component.spec.ts_**: The _"app.component.spec.ts"_ file contains unit tests for the root component. 111 | 112 | - **_src/assets/_**: The _"assets"_ directory contains static resources for the application, such as images, JSON files, etc. 113 | 114 | - **_src/environments/_**: Here, you will find environment-specific configurations, such as environment variables for different development, testing, and production environments. 115 | 116 | - **_src/index.html_**: The _"index.html"_ file is the main HTML page of the application, where the Angular app is bootstrapped. 117 | 118 | - **_src/main.ts_**: The _"main.ts"_ file is the entry point of the Angular application. It calls the _platformBrowserDynamic().bootstrapModule()_ function to initialize the root module _"AppModule"_. 119 | 120 | - **_src/styles.css_**: The _"styles.css"_ file is the global stylesheet for the application, defining styles that affect all components. 121 | 122 | - **_angular.json_**: The _"angular.json"_ file contains the configuration for the Angular project, such as global styles, scripts, build configurations, and other Angular CLI-specific settings. 123 | 124 | - **_package.json_**: The _"package.json"_ file is used by npm to manage the project's dependencies and store information about the project, such as its name, version, scripts, etc. 125 | 126 | - **_tsconfig.json_**: The _"tsconfig.json"_ file is the TypeScript configuration file, where you can define the TypeScript compiler settings for the project. 127 | 128 | 129 | ## Hands on 130 | 131 | See [Task: Create Angular Project](https://github.com/persapiens-classes/account-frontend/issues/1) of Angular Example App. 132 | -------------------------------------------------------------------------------- /class/4-angular/10-data-binding.md: -------------------------------------------------------------------------------- 1 | # Angular Data Binding 2 | 3 | ### What is Data Binding? 4 | 5 | Data Binding is one of the core features of Angular. It allows you to connect model data (**component class**) with the template (**user interface**), enabling changes made to the data to be automatically reflected in the user interface and vice versa. 6 | 7 | There are four main types of data binding in Angular: _Interpolation_; _Property Binding_; _Event Binding_; _Two-Way Binding_. 8 | 9 | ### Interpolation `{{ }}` 10 | Interpolation is a simple form of data binding that allows you to display model values in the template, within text elements or attributes. 11 | 12 | Example: 13 | ```html 14 |

{{ title }}

15 |

{{ description }}

16 | ``` 17 | 18 | ### Property Binding `[ ]` 19 | 20 | Property Binding allows you to assign model property values to HTML element attributes. 21 | 22 | Example: 23 | 24 | ```html 25 | 26 | ``` 27 | 28 | ### Event Binding `( )` 29 | 30 | Event Binding allows you to bind events (such as clicks, mouseover, etc.) to component model methods. 31 | 32 | Example: 33 | ```html 34 | 35 | ``` 36 | 37 | ### Two-Way Binding `[( )]` 38 | 39 | Two-Way Binding combines *Property Binding* and *Event Binding*. It maintains bidirectional synchronization between the model and the template. Any model or template changes will automatically reflect in the other. 40 | 41 | Example: 42 | ```html 43 | 44 |

Hello, {{ name }}!

45 | ``` 46 | 47 | **How to enable Two-Way Binding?** 48 | 49 | To use *Two-Way Binding*, import the **FormsModule** in your main module (usually *app.module.ts*). Make sure the import is correctly included in the imports array of the NgModule: 50 | 51 | ```typescript 52 | import { NgModule } from '@angular/core'; 53 | import { BrowserModule } from '@angular/platform-browser'; 54 | import { FormsModule } from '@angular/forms'; // Import FormsModule 55 | 56 | import { AppComponent } from './app.component'; 57 | 58 | @NgModule({ 59 | declarations: [AppComponent], 60 | imports: [BrowserModule, FormsModule], // Add FormsModule here 61 | providers: [], 62 | bootstrap: [AppComponent], 63 | }) 64 | export class AppModule {} 65 | ``` 66 | 67 | **Data Binding Notes** 68 | 69 | - Data Binding is a powerful way to connect model data and the template, making the application more dynamic and responsive to changes in the data. 70 | - It is important to be cautious to avoid infinite update loops when using Two-Way Binding, as changes in the model can trigger continuous updates in the template and vice versa. 71 | - When using Two-Way Binding with the ngModel directive, remember to import FormsModule as explained earlier. 72 | 73 | ### Resume 74 | 75 | Angular Data Binding is one of the main reasons the framework is so efficient for developing reactive and interactive web applications. 76 | 77 | With Data Binding, you can create dynamic and responsive user interfaces, making it easier for users to interact with your application. 78 | 79 | ## Angular Class and Style Binding 80 | 81 | In addition to the four main types of data binding mentioned earlier, Angular provides additional features to bind CSS classes and styles directly to the template. 82 | 83 | These features are known as **Class Binding** and **Style Binding**. 84 | 85 | ### Class Binding 86 | 87 | **Class Binding** allows you to dynamically add or remove CSS classes to HTML elements based on model property values. This is useful when you want to change the style of an element based on certain conditions or states of the application. 88 | 89 | Example: 90 | 91 | ```html 92 | 93 | ``` 94 | 95 | In this example, the CSS class **"button-new"** will be added to the button only when the **isNew** property in the component is true. 96 | 97 | ### Style Binding 98 | 99 | Style Binding lets you set CSS styles directly in the template based on model property values. This lets you dynamically change style properties like color, size, margins, etc. 100 | 101 | Example: 102 | 103 | ```html 104 |

This text has a dynamic color

105 | ``` 106 | 107 | In this example, the paragraph's **color** CSS style will be set based on the value of the **corTexto** property in the component. 108 | 109 | **Applying Conditions with Class and Style Binding** 110 | 111 | In addition to adding classes and styles, you can apply complex conditions using **ternary expressions** or the **&&** (AND) operator to combine multiple conditions. 112 | 113 | Example using ternary expression: 114 | 115 | ```html 116 | 117 | ``` 118 | 119 | Example using the && (AND) operator: 120 | 121 | ```html 122 | 123 | ``` 124 | 125 | **Class and Style Binding in Two-Way Binding** 126 | 127 | Combining Class Binding or Style Binding with Two-Way Binding creates highly dynamic and interactive user interfaces. 128 | 129 | Example with Two-Way Binding and Class Binding: 130 | 131 | ```html 132 | 133 | ``` 134 | 135 | In this example, the value of the `classCSS` property in the model is bound to the class attribute of the input element, allowing the user to change the applied CSS class dynamically. 136 | 137 | *Summary* 138 | 139 | Class Binding and Style Binding are powerful Angular features for dynamically applying styles and classes in the template based on model properties. These functionalities make developing interactive and reactive user interfaces easier and more efficient, allowing you to create more dynamic applications with a better user experience. 140 | 141 | 142 | ## 👷 Task 143 | 144 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 145 | 146 | - Create an angular project in Github. 147 | - Include a devcontainer to work with typescript. You can use [Ria Angular Example](https://github.com/persapiens-classes/ifrn-angular-ria-angular-example). 148 | - Create an insert, list, and remove crud operations of a model in the template. Your model should have 3 attributes: string, number, and boolean. 149 | -------------------------------------------------------------------------------- /class/4-angular/18-http-client.md: -------------------------------------------------------------------------------- 1 | ## HttpClient 2 | 3 | **What is HttpClient?** 4 | 5 | - The *HttpClient* is an Angular module that provides an easy way to make HTTP requests in Angular applications. 6 | - It is a class that is part of the *@angular/common/http* module. 7 | 8 | **Why is it important?** 9 | 10 | - Many web applications need to interact with servers to fetch or send data. The *HttpClient* makes this possible efficiently and in an organized manner. 11 | - It handles low-level details, such as creating and managing HTTP requests and responses. 12 | 13 | **How does it fit into Web Development?** 14 | 15 | - The *HttpClient* is used to communicate with RESTful APIs, web services, and other HTTP resources. 16 | - It is an essential part of front-end development when you need to fetch data from or update data on a server. 17 | 18 | **Basic HttpClient Configuration** 19 | 20 | ```typescript 21 | import { HttpClient } from '@angular/common/http'; 22 | 23 | constructor(private http: HttpClient) { } 24 | ``` 25 | 26 | - To use HttpClient, first import it from the **@angular/common/http** module. 27 | - Then, inject it as a dependency in the constructor of a component or service. 28 | - Now you can use *this.http* to make HTTP requests in your application. 29 | 30 | See [Angular HttpClient Official Reference.](https://angular.dev/guide/http) 31 | 32 | 33 | --- 34 | 35 | ## HttpClient and RxJS 36 | 37 | RxJS is a JavaScript library that has become one of the fundamental pillars in modern web application development, especially in reactive and asynchronous environments. 38 | 39 | Here are some key concepts related to RxJS: 40 | 41 | 1. **Observables**: Observables are at the core of RxJS. They represent a data source that can emit values over time. These values can be DOM events, API responses, user clicks, or anything else you want to observe. 42 | 43 | 2. **Operators**: Operators are functions that allow you to transform, filter, combine, and manipulate the data that flows through an Observable. There are many available operators, such as **map**, **filter**, **merge**, **concat**, and many others. 44 | 45 | 3. **Subscriptions**: A Subscription is an object that represents the execution of an Observable and allows you to unsubscribe from it when it's no longer needed. This is important to prevent memory leaks. 46 | 47 | 4. **Observers**: Observers are the consumers of Observables. They define what to do when an Observable emits values, usually in the form of functions that handle those values. 48 | 49 | 5. **Asynchronous Data Flow**: RxJS is especially useful when working with asynchronous operations, such as API requests, DOM events, or anything not directly controlled by your code. 50 | 51 | 6. **Reactive Programming**: Reactive programming is a programming paradigm that focuses on the propagation of state changes. With RxJS, you can create reactive data pipelines that automatically respond to data changes. 52 | 53 | 7. **Cross-Platform Compatibility**: RxJS is a JavaScript library, but its ideas and concepts can be applied in many programming languages. There are Rx implementations in other languages, such as RxJava for Java and RxSwift for Swift. 54 | 55 | HttpClient and RxJS have a close relationship in the context of Angular application development. 56 | See [Angular Making HTTP requests.](https://angular.dev/guide/http/making-requests) 57 | 58 | - **Observables in HttpClient**: HttpClient uses **RxJS** Observables to handle HTTP requests and responses in an asynchronous and reactive way. When you make an HTTP request using HttpClient, it returns an Observable that you can subscribe to in order to receive the results. 59 | 60 | - **Handling Asynchronous Responses**: HTTP requests are asynchronous operations, since you're waiting for a response from the server. **RxJS** is a library that efficiently handles asynchronous data streams and events. Therefore, HttpClient uses RxJS Observables to handle these responses reactively. 61 | 62 | - **RxJS Operators with HttpClient**: You can use RxJS operators alongside HttpClient to manipulate and transform response data. For example, you can use the **map** operator to transform the response data before processing it, or use the **catchError** operator to handle request errors. 63 | 64 | ### Getting Data via REST API (HTTP GET) 65 | 66 | - Retrieving data from a server 67 | - Using the **.get()** method 68 | 69 | ```typescript 70 | this.http.get('https://api.example.com/data').subscribe(data => { 71 | console.log(data); 72 | }); 73 | ``` 74 | 75 | ### Updating Data via REST API (HTTP PUT) 76 | 77 | - Updating data on the server 78 | - Using the **.put()** method 79 | 80 | ```typescript 81 | const newData = { name: 'New Name', age: 25 }; 82 | this.http.put('https://api.example.com/data/1', newData).subscribe(response => { 83 | console.log(response); 84 | }); 85 | ``` 86 | 87 | ### Deleting Data via REST API (HTTP DELETE) 88 | 89 | - Deleting data on the server 90 | - Using the **.delete()** method 91 | 92 | ```typescript 93 | this.http.delete('https://api.example.com/data/1').subscribe(response => { 94 | console.log(response); 95 | }); 96 | ``` 97 | 98 | ### Inserting New Data via REST API (HTTP POST) 99 | 100 | - Sending new data to the server 101 | - Using the **.post()** method 102 | 103 | ```typescript 104 | const newData = { name: 'New Name', age: 25 }; 105 | this.http.post('https://api.example.com/data', newData).subscribe(response => { 106 | console.log(response); 107 | }); 108 | ``` 109 | 110 | ## Handling Errors 111 | 112 | - Error handling with *catchError* 113 | - Example of error handling 114 | 115 | ```typescript 116 | this.http.get('https://api.example.com/data').pipe( 117 | catchError(error => { 118 | console.error('Error:', error); 119 | return throwError(() => new Error('Something went wrong.')); 120 | }) 121 | ).subscribe(data => { 122 | console.log(data); 123 | }); 124 | ``` 125 | 126 | --- 127 | 128 | ## 👷 Task 129 | 130 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 131 | 132 | - Create Auth service to sign in some backend system, keeping jwt token in localStorage. 133 | - Create Login component to sign in using Auth service. Refactor routers to do login as initial page. 134 | - Using authentication token, protect routers to other componentes with [Angular Guard](https://angular.dev/api/router/CanActivate). 135 | - Create model service using httpClient to do CRUD options in backend system, adding jwt token with [Angular Http Interceptors](https://angular.dev/guide/http/interceptors). 136 | 137 | You can use tasks [Create Auth Service to sign in Account Backend](https://github.com/persapiens-classes/account-frontend/issues/18), [Create Login Component using sign in of AuthService](https://github.com/persapiens-classes/account-frontend/issues/20), [Protect routers to other components with Angular Guard (Authenticated User) ](https://github.com/persapiens-classes/account-frontend/issues/22), [Create owner service using httpclient to do crud options in account backend system](https://github.com/persapiens-classes/account-frontend/issues/25) of the Account Frontend. 138 | -------------------------------------------------------------------------------- /class/4-angular/13-components.md: -------------------------------------------------------------------------------- 1 | ### **Angular Components** 2 | 3 | Components are essential building blocks of Angular. They play a central role in the framework's architecture, enabling you to create reusable and independent parts of the user interface, each with its own logic, template, and style. 4 | 5 | --- 6 | 7 | ### **Creating a Component** 8 | 9 | To create a new component, you can use the Angular CLI (Command Line Interface) with the following command: 10 | 11 | ```bash 12 | ng generate component component-name 13 | ``` 14 | 15 | This will generate a file structure for the new component, including a **.ts** file (component logic), **.html** file (template), and **.css** file (styles), among others. 16 | 17 | --- 18 | 19 | **Structure of a Component:** 20 | 21 | An Angular component consists of three main parts: 22 | 23 | - the @Component decorator 24 | - the component class 25 | - the associated template. 26 | 27 | **Example:** 28 | 29 | ```typescript 30 | import { Component } from "@angular/core"; 31 | 32 | @Component({ 33 | selector: "app-example", // Component selector used in the template. 34 | templateUrl: "./example.component.html", // Path to the component's template. 35 | styleUrls: ["./example.component.scss"], // Component's style files. 36 | }) 37 | export class ExampleComponent { 38 | // Component logic here... 39 | } 40 | ``` 41 | 42 | --- 43 | 44 | **Using a Component:** 45 | 46 | You can use a component within other components or templates by referencing the selector defined in the @Component decorator. 47 | 48 | **Example of Using a Component:** 49 | 50 | ```html 51 | 52 | ``` 53 | 54 | --- 55 | 56 | ### **Communication Between Components** 57 | 58 | Components can communicate with each other through inputs and outputs. 59 | 60 | --- 61 | 62 | #### **Inputs:** 63 | 64 | Allow a parent component to pass data to a child component. 65 | 66 | ```typescript 67 | import { Component, Input } from "@angular/core"; 68 | 69 | @Component({ 70 | selector: "app-child", 71 | template: "

{{ message }}

", 72 | }) 73 | export class ChildComponent { 74 | @Input() message: string; 75 | } 76 | ``` 77 | 78 | ```html 79 | 80 | ``` 81 | 82 | --- 83 | 84 | #### **Outputs:** 85 | 86 | Allow a child component to emit events to a parent component. 87 | 88 | **Child Component Configuration:** 89 | 90 | ```typescript 91 | import { Component, Output, EventEmitter } from "@angular/core"; 92 | 93 | @Component({ 94 | selector: "app-child", 95 | template: '', 96 | }) 97 | export class ChildComponent { 98 | @Output() messageOutEvent = new EventEmitter(); 99 | 100 | onClickSend() { 101 | this.messageOutEvent.emit("Message from Child"); 102 | } 103 | } 104 | ``` 105 | 106 | **Parent Component Configuration - Template:** 107 | 108 | ```html 109 | 110 | ``` 111 | 112 | **Parent Component Configuration - Class:** 113 | 114 | ```typescript 115 | ... 116 | parentAction(event: string): void { 117 | alert(event); 118 | } 119 | ... 120 | ``` 121 | 122 | For more details on component communication, refer to the Angular documentation about [inputs](https://angular.dev/guide/components/inputs) and [outputs](https://angular.dev/guide/components/outputs). 123 | 124 | --- 125 | 126 | ### **Component Lifecycle** 127 | 128 | The lifecycle of an Angular component consists of a series of events that occur from its creation to its destruction. Each event provides an opportunity to perform specific actions at key moments during the component's lifespan. 129 | 130 | Here are the main lifecycle events of a component, along with examples demonstrating how to use them: 131 | 132 | --- 133 | 134 | #### **ngOnInit** 135 | 136 | The `ngOnInit` event is triggered right after a component is initialized. It's a good place to perform initializations, such as fetching data from a service or setting up variables. 137 | 138 | ```typescript 139 | import { Component, OnInit } from "@angular/core"; 140 | 141 | @Component({ 142 | selector: "app-example", 143 | template: "

{{ message }}

", 144 | }) 145 | export class ExampleComponent implements OnInit { 146 | message: string; 147 | 148 | ngOnInit() { 149 | this.message = "Hello, world!"; 150 | } 151 | } 152 | ``` 153 | 154 | --- 155 | 156 | #### **ngOnChanges** 157 | 158 | The `ngOnChanges` event is triggered whenever an input value (`@Input`) changes. It provides an object containing the detected changes. 159 | 160 | ```typescript 161 | import { Component, Input, OnChanges, SimpleChanges } from "@angular/core"; 162 | 163 | @Component({ 164 | selector: "app-child", 165 | template: "

{{ message }}

", 166 | }) 167 | export class ChildComponent implements OnChanges { 168 | @Input() message: string; 169 | 170 | ngOnChanges(changes: SimpleChanges) { 171 | if (changes.message) { 172 | console.log("Message value changed to:", changes.message.currentValue); 173 | } 174 | } 175 | } 176 | ``` 177 | 178 | --- 179 | 180 | #### **ngDoCheck** 181 | 182 | The `ngDoCheck` event is triggered whenever change detection is executed. It can be used to perform manual change checks. 183 | 184 | ```typescript 185 | import { Component, DoCheck } from "@angular/core"; 186 | 187 | @Component({ 188 | selector: "app-example", 189 | template: "

{{ counter }}

", 190 | }) 191 | export class ExampleComponent implements DoCheck { 192 | counter: number = 0; 193 | 194 | ngDoCheck() { 195 | console.log("ngDoCheck executed."); 196 | // Logic for manual change detection here... 197 | } 198 | } 199 | ``` 200 | 201 | --- 202 | 203 | #### **ngOnDestroy** 204 | 205 | The `ngOnDestroy` event is triggered when a component is about to be destroyed. It is used to perform cleanup actions, such as canceling subscriptions or disconnecting from services. 206 | 207 | ```typescript 208 | import { Component, OnDestroy } from "@angular/core"; 209 | 210 | @Component({ 211 | selector: "app-example", 212 | template: "

Component will be destroyed soon.

", 213 | }) 214 | export class ExampleComponent implements OnDestroy { 215 | ngOnDestroy() { 216 | console.log("Component destroyed."); 217 | // Cleanup actions here... 218 | } 219 | } 220 | ``` 221 | 222 | --- 223 | 224 | **Note:** 225 | 226 | Remember that lifecycle events are optional, and you don't need to implement all of them in every component. Choose the events that are relevant to what you want to achieve and use them as needed. 227 | 228 | In addition to the main Angular lifecycle methods such as `ngOnInit`, `ngOnChanges`, `ngDoCheck`, and `ngOnDestroy`, there are other methods like **ngAfterContentInit**, **ngAfterContentChecked**, **ngAfterViewInit**, and **ngAfterViewChecked** that provide opportunities to interact with projected content and the component's view. Understanding and utilizing these methods appropriately will enable you to control and optimize your component's logic across different lifecycle phases. 229 | 230 | ## 👷 Task 231 | 232 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 233 | 234 | - Refactor that app component of the project in previous task (12-ui-components) to use dedicated insert, update, detail, remove, and list components. 235 | 236 | You can use tasks [Create hello, insert and list components](https://github.com/persapiens-classes/account-frontend/issues/8) and [Improve owner crud](https://github.com/persapiens-classes/account-frontend/issues/10) of Angular Example Project. 237 | -------------------------------------------------------------------------------- /class/4-angular/15-routers.md: -------------------------------------------------------------------------------- 1 | ### **Angular Router** 2 | 3 | Routing is a key part of many modern web applications, enabling users to navigate between different sections of the app without reloading the page. Angular offers a robust routing module that simplifies navigation between components and views. 4 | 5 | --- 6 | 7 | ### **Creating the Routing Module** 8 | 9 | You need to create the routing module, `_AppRoutingModule_`, and define the application's routes in it. If this module was not created during project initialization, execute the following command: 10 | 11 | ```bash 12 | ng generate module app-routing --flat --module=app 13 | ``` 14 | 15 | --- 16 | 17 | ### **Setting Up Routing** 18 | 19 | There are three fundamental steps to creating a route: 20 | 21 | --- 22 | 23 | 1. **Import the Routing Module in the `_app.module.ts_` file** 24 | 25 | Import the **AppRoutingModule** into the **AppModule** and add it to the imports array. 26 | 27 | ```typescript 28 | import { BrowserModule } from '@angular/platform-browser'; 29 | import { NgModule } from '@angular/core'; 30 | import { AppRoutingModule } from './app-routing.module'; // Import AppRoutingModule 31 | import { AppComponent } from './app.component'; 32 | 33 | @NgModule({ 34 | declarations: [AppComponent], 35 | imports: [ 36 | BrowserModule, 37 | AppRoutingModule, // Add AppRoutingModule to the imports array 38 | ], 39 | providers: [], 40 | bootstrap: [AppComponent], 41 | }) 42 | export class AppModule {} 43 | ``` 44 | 45 | --- 46 | 47 | 2. **Import `RouterModule` and `Routes` into your routing module (`_AppRoutingModule_`)** 48 | 49 | ```typescript 50 | import { RouterModule, Routes } from '@angular/router'; // Import RouterModule and Routes 51 | 52 | const routes: Routes = []; // Array of routes 53 | 54 | @NgModule({ 55 | imports: [RouterModule.forRoot(routes)], 56 | exports: [RouterModule], 57 | }) 58 | export class AppRoutingModule {} 59 | ``` 60 | 61 | --- 62 | 63 | 3. **Define routes in the `Routes` array** 64 | 65 | Each route in the array is a JavaScript object with two properties. The first, **path**, defines the URL path for the route. The second, **component**, specifies the Angular component to use for the corresponding path. 66 | 67 | ```typescript 68 | const routes: Routes = [ 69 | { path: '', component: HomeComponent }, 70 | { path: 'about', component: AboutComponent }, 71 | { path: 'contact', component: ContactComponent }, 72 | ]; 73 | ``` 74 | 75 | --- 76 | 77 | ### **Navigating Between Routes** 78 | 79 | Navigation between routes can be achieved using the `_routerLink_` directive in templates or the `_Router_` service in code. 80 | 81 | **Using `routerLink` in a Template** 82 | 83 | ```html 84 | Home 85 | About 86 | Contact 87 | ``` 88 | 89 | **Displaying Routes in the Template** 90 | 91 | ```html 92 | 93 | ``` 94 | 95 | **Programmatic Navigation with `_Router_`** 96 | 97 | ```typescript 98 | import { Router } from '@angular/router'; 99 | 100 | // ... 101 | 102 | constructor(private router: Router) {} 103 | 104 | navigateToAbout() { 105 | this.router.navigate(['/about']); 106 | } 107 | ``` 108 | 109 | --- 110 | 111 | ### **Routing with Parameters** 112 | 113 | You can pass parameters to routes to enable components to display specific information. 114 | 115 | **Defining a Route with a Parameter** 116 | 117 | ```typescript 118 | { path: 'product/:id', component: ProductDetailsComponent } 119 | ``` 120 | 121 | **Accessing the Parameter in a Component** 122 | 123 | ```typescript 124 | import { ActivatedRoute } from '@angular/router'; 125 | 126 | // ... 127 | 128 | constructor(private route: ActivatedRoute) {} 129 | 130 | ngOnInit() { 131 | this.route.paramMap.subscribe(params => { 132 | const productId = params.get('id'); 133 | // Logic to load product details by ID 134 | }); 135 | } 136 | ``` 137 | 138 | **Using `routerLink` in a Template** 139 | 140 | ```html 141 | View Product 142 | ``` 143 | 144 | --- 145 | 146 | ### **Routing with Query Parameters** 147 | 148 | Angular also supports **query parameters** to pass information between routes. Query parameters appear in the URL after the question mark (**?**) and are often used for filtering, sorting, or providing additional data. 149 | 150 | **Steps to Define Routes with Query Parameters:** 151 | 152 | 1. **Define the Route in `_AppRoutingModule.ts_`** 153 | 154 | ```typescript 155 | { path: 'search', component: SearchComponent } 156 | ``` 157 | 158 | 2. **Set Query Parameters in the Template** 159 | 160 | ```html 161 | Search 162 | ``` 163 | 164 | **Accessing Query Parameters in the Component:** 165 | 166 | 1. Import the _ActivatedRoute_ module: 167 | 168 | ```typescript 169 | import { ActivatedRoute } from '@angular/router'; 170 | ``` 171 | 172 | 2. Access the Query Parameters: 173 | 174 | ```typescript 175 | constructor(private route: ActivatedRoute) {} 176 | 177 | ngOnInit() { 178 | this.route.queryParams.subscribe(params => { 179 | const filter = params['filter']; 180 | const order = params['order']; 181 | // Logic to handle query parameters 182 | }); 183 | } 184 | ``` 185 | 186 | **Programmatic Navigation with Query Parameters** 187 | 188 | ```typescript 189 | import { Router } from '@angular/router'; 190 | 191 | // ... 192 | 193 | constructor(private router: Router) {} 194 | 195 | navigateWithQueryParams() { 196 | const queryParams = { 197 | filter: 'active', 198 | order: 'desc', 199 | }; 200 | 201 | this.router.navigate(['/search'], { queryParams }); 202 | } 203 | ``` 204 | 205 | --- 206 | 207 | ### **Routing with Redirects** 208 | 209 | You can define redirects to ensure that outdated URLs are redirected to updated routes. 210 | 211 | ```typescript 212 | { path: 'old-page', redirectTo: '/new-route' } 213 | ``` 214 | 215 | --- 216 | 217 | ### **Wildcard Routes** 218 | 219 | To handle cases where users navigate to a non-existent part of your application, configure a wildcard route. Angular will select this route whenever the requested URL does not match any defined routes. 220 | 221 | **Example** 222 | 223 | ```typescript 224 | { path: '**', component: PageNotFoundComponent } 225 | ``` 226 | 227 | The two asterisks indicate that this is a wildcard route. For the component property, you can specify any component in your app. Common choices include a dedicated **PageNotFoundComponent** for displaying a **404 page** or a redirect to the app's main component. 228 | 229 | --- 230 | 231 | ### **Route Guards** 232 | 233 | Route guards allow you to control access to routes based on specific conditions, such as authentication or authorization. 234 | 235 | ```typescript 236 | import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router'; 237 | 238 | @Injectable({ 239 | providedIn: 'root', 240 | }) 241 | export class AuthenticationGuard implements CanActivate { 242 | canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree { 243 | // Authentication logic here 244 | } 245 | } 246 | ``` 247 | 248 | ## 👷 Task 249 | 250 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 251 | 252 | - Create routers to switch between inserting, updating, and listing components of your model project in the previous task (14 services). 253 | 254 | You can use task [Add Router to Insert and List Components](https://github.com/persapiens-classes/account-frontend/issues/14) of the Angular Example Project. 255 | -------------------------------------------------------------------------------- /class/4-angular/11-directives.md: -------------------------------------------------------------------------------- 1 | ## Angular Directives 2 | 3 | Directives are a fundamental part of Angular, allowing you to extend HTML syntax to **add custom behaviors** to page elements. 4 | 5 | There are three main types of directives in Angular: 6 | 7 | - Attribute Directives 8 | - Structural Directives 9 | - Component Directives 10 | 11 | ### Attribute Directives 12 | 13 | Attribute Directives are used to change the behavior of existing HTML elements by adding or modifying attributes and behaviors. They are applied as attributes to elements in the template. 14 | 15 | Examples: 16 | 17 | ```html 18 | 19 |

I am an attribute directive

20 | ``` 21 | 22 | ```html 23 | 24 |

Attribute Directive - [ngClass]

25 | ``` 26 | 27 | The **NgStyle** and **NgClass** directives are attribute directives used to dynamically alter the style of any DOM element based on a condition. 28 | 29 | [Official Documentation for NgStyle](https://angular.dev/guide/directives#setting-inline-styles-with-ngstyle) 30 | [Official Documentation for NgClass](https://angular.dev/guide/directives#adding-and-removing-classes-with-ngclass) 31 | 32 | ### Structural Directives 33 | 34 | Structural Directives manipulate the DOM structure by adding or removing HTML elements from the template. They are applied as structural attributes on HTML elements. 35 | 36 | #### ngIf Directive 37 | 38 | Example: 39 | 40 | ```html 41 | 42 |
This element will only display if showElement is true.
43 | ``` 44 | 45 | Here, **'\*ngIf'** is a Structural Directive that adds or removes the `
` element based on the value of **'showElement'**. 46 | 47 | [Official Documentation for NgIf](https://angular.dev/guide/directives#adding-or-removing-an-element-with-ngif) 48 | 49 | #### ngFor Directive 50 | 51 | The **\*ngFor** directive is one of the most commonly used structural directives in Angular. It allows you to iterate over a collection of items and render them in the template. Using \*ngFor, you can dynamically create lists, tables, or repeat elements based on the model's data. 52 | 53 | Example: 54 | 55 | The syntax for \*ngFor is simple and involves assigning a local variable to each item in the collection you want to iterate. The directive can be applied to any HTML element in the template. 56 | 57 | ```html 58 |
{{ item }}
59 | ``` 60 | 61 | In this example, we are iterating over a collection called _items_, and for each item in the collection, the template renders a new **
** containing the item's value. 62 | 63 | **Item Index:** In addition to the item's value, you can access the item's index in the loop and track items by a unique property. 64 | 65 | Accessing the Index: 66 | 67 | ```html 68 |
Item {{ i }}: {{ item }}
69 | ``` 70 | 71 | [Official Documentation for NgFor](https://angular.dev/guide/directives#listing-items-with-ngfor) 72 | 73 | #### ngSwitch, ngSwitchCase, and ngSwitchDefault Directive 74 | 75 | The **ngSwitch** directive is a structural directive in Angular that allows you to create conditional statements in the template based on an expression. It provides a more readable and organized way to handle conditional logic than using multiple **\*ngIf** directives. 76 | 77 | **ngSwitch Syntax:** 78 | 79 | The **ngSwitch** syntax resembles a JavaScript switch. The **ngSwitch** directive is applied to a parent element containing multiple **ngSwitchCase** child elements and an optional **ngSwitchDefault** element. 80 | 81 | ```html 82 |
83 |
Content 1
84 |
Content 2
85 |
Content 3
86 |
Default content
87 |
88 | ``` 89 | 90 | 1. The **[ngSwitch]** attribute receives an expression compared against the **ngSwitchCase** values. 91 | 2. Each **ngSwitchCase** element contains a value that is compared with the **ngSwitch** expression. The content of the **ngSwitchCase** is rendered if the expression matches its value. 92 | 3. The **ngSwitchDefault** element is optional and is rendered if the expression does not match any of the **ngSwitchCase** values. 93 | 94 | Example: 95 | 96 | ```html 97 |
98 |

You chose option A

99 |

You chose option B

100 |

You chose option C

101 |

Please choose a valid option (A, B, or C).

102 |
103 | ``` 104 | 105 | **Note:** 106 | 107 | The **ngSwitchCase** value is enclosed in single quotes because it is a string. If you're using numbers or other variables, quotes are not required. 108 | 109 | Using ngSwitch with Numbers: 110 | 111 | ```html 112 |
113 |

You chose option 1

114 |

You chose option 2

115 |

You chose option 3

116 |

Please choose a valid option (1, 2, or 3).

117 |
118 | ``` 119 | 120 | [Official Documentation for NgSwitch](https://angular.dev/guide/directives#switching-cases-with-ngswitch) 121 | 122 | #### New Syntax for Structural Directives 123 | 124 | Starting with Angular 17, a new syntax for flow control in templates was introduced, replacing traditional structural directives like \*ngIf, \*ngFor, and \*ngSwitch. This new approach uses @if, @for, and @switch syntax, providing a more intuitive and JavaScript-like way to express conditional and loop logic in templates. 125 | 126 | Example of @if, @for, @switch: 127 | 128 | ```javascript 129 | @if (condition) { 130 | 131 | } @else if (b > a) { 132 | {{a}} is less than {{b}} 133 | } @else { 134 | {{a}} is equal to {{b}} 135 | } 136 | 137 | @for (let item of list) { 138 | 139 | } @empty { 140 | 141 | } 142 | 143 | @switch (variable) { 144 | @case ('value1') { 145 | 146 | } 147 | @case ('value2') { 148 | 149 | } 150 | @default { 151 | 152 | } 153 | } 154 | ``` 155 | 156 | #### Custom Directive 157 | 158 | You can also create your own custom Directives in Angular. To do this, you need to use the @Directive decorator and implement the required logic for the directive. 159 | 160 | Example of a Custom Attribute Directive: 161 | 162 | ```typescript 163 | import { Directive, ElementRef, HostListener } from "@angular/core"; 164 | 165 | @Directive({ 166 | selector: "[appHighlight]", // Selector for using the directive in the template. 167 | }) 168 | export class HighlightDirective { 169 | constructor(private el: ElementRef) {} 170 | 171 | @HostListener("mouseenter") onMouseEnter() { 172 | this.highlightText("yellow"); 173 | } 174 | 175 | @HostListener("mouseleave") onMouseLeave() { 176 | this.highlightText(null); 177 | } 178 | 179 | private highlightText(color: string) { 180 | this.el.nativeElement.style.backgroundColor = color; 181 | } 182 | } 183 | ``` 184 | 185 | Example: 186 | 187 | ```html 188 | 189 |

This paragraph will be highlighted

190 | ``` 191 | 192 | Here, **'appHighlight'** is a custom Attribute Directive that changes the style of the paragraph when **'highlightText'** is true. 193 | In this example, we created a custom Attribute Directive named **appHighlight**, which highlights the text of the element when the mouse enters its area and removes the highlight when the mouse leaves. 194 | 195 | Use the following command to generate directives: 196 | 197 | ```node 198 | ng generate directive 199 | ``` 200 | 201 | [Official Documentation for Building Directives - Standalone Project](https://angular.dev/guide/directives/attribute-directives) 202 | [Official Documentation for Building Directives - Module-Based Project](https://angular.dev/guide/directives/attribute-directives) 203 | 204 | --- 205 | 206 | ## Final Considerations 207 | 208 | Directives are a powerful and versatile feature in Angular, allowing you to create custom and reusable behaviors in templates. By combining Directives with other Angular features like Data Binding and Services, you can build more interactive and dynamic web applications, facilitating the maintenance and development of rich user interfaces. 209 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /class/4-angular/16-forms.md: -------------------------------------------------------------------------------- 1 | ## Forms in Angular 2 | 3 | Handling user input with forms is the foundation of many common applications. Forms are used in applications to enable users to log in, update profiles, enter sensitive information, and perform many other data entry tasks. 4 | 5 | Angular provides a powerful forms module that simplifies creating, validating, and managing complex and dynamic forms. 6 | 7 | There are two main types of forms in Angular: **Template-Driven and Reactive (Model-Driven).** 8 | 9 | ### Template-Driven Forms 10 | 11 | Template-Driven forms are simpler and based on HTML templates. Validation is primarily handled in HTML, and most of the logic is automatically managed by Angular. 12 | 13 | Example: 14 | 15 | ```html 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | ``` 26 | 27 | **Code Details:** 28 | 29 | - **form**: The root form element. The attribute **#myForm="ngForm"** binds the form to a variable named `myForm`, which is used to access the form's state and controls. When the form is submitted, the method **onSubmit('myForm')** will be triggered in the component class. 30 | 31 | - **label**: Label identifying the input field for the user. 32 | 33 | - **input**: Input element for the user to enter data. The `type` attribute defines the type of input (e.g., text or email). The *`id`* attribute must match the *`for`* attribute of the label to link them. The *`name`* attribute identifies the fields in the form. 34 | 35 | - **ngModel**: Angular directive that creates a two-way binding between the input fields and the data model. It allows direct access to and updates of the field values in the component. 36 | 37 | - **required**: Directive specifying that the field is required. 38 | 39 | - **email**: Directive that validates whether the field contains a valid email address. 40 | 41 | - **button**: Button to submit the form. When clicked, the form will be submitted. 42 | 43 | **Validation and Submission** 44 | 45 | Validation automatically occurs based on the directives applied to the input fields. If a required field is empty or the email format is incorrect, Angular will mark the field as invalid. 46 | 47 | ```text 48 | Note: To work with template-driven forms, you must import the `FormsModule` in the `app.module.ts` file. 49 | ``` 50 | 51 | ### Form Validation 52 | 53 | Form validation ensures that the user input is correct and valid. Angular provides ways to validate forms in both Template-Driven and Reactive (Model-Driven) modes. 54 | 55 | ### Validation in Template-Driven Forms 56 | 57 | **Required Field Validation** 58 | 59 | ```html 60 | 61 | 62 |
63 | Name is required. 64 |
65 | ``` 66 | 67 | Explanation: 68 | 69 | - We use the *required* directive to define that the field is mandatory. 70 | - We use the local variable *#name* to access the field's state in the template. 71 | - The expression **ngIf="name.invalid && (name.dirty || name.touched)"** checks if the field is invalid and has been touched or modified. If these conditions are met, the *div* element with the error message will be displayed. 72 | 73 | **Email Format Validation** 74 | 75 | ```html 76 | 77 | 78 |
79 | Enter a valid email. 80 |
81 | ``` 82 | 83 | Explanation: 84 | 85 | - Besides the *required* directive, we use the *email* directive to validate the email format. 86 | - Similar to the previous example, we check if the field is invalid and has been touched or modified to display the error message. 87 | 88 | **Min and Max Length Validation** 89 | 90 | ```html 91 | 92 | 93 |
94 | Password must be between 6 and 12 characters long. 95 |
96 | ``` 97 | 98 | Explanation: 99 | 100 | - We add *#password="ngModel"* to declare the local variable *password* and associate it with ngModel. 101 | - The *minlength* and *maxlength* directives are used to define the password length limits. 102 | - If the password is shorter than 6 or longer than 12 characters, the validation is triggered, and the error message is displayed. 103 | 104 | **Field Comparison Validation (Password Confirmation)** 105 | 106 | ```html 107 | 108 | 109 | 110 | 111 |
112 | Passwords do not match. 113 |
114 | ``` 115 | 116 | Explanation: 117 | 118 | - We add *#confirmPassword="ngModel"* to declare the local variable *confirmPassword* and associate it with ngModel. 119 | - In the password confirmation field, we use the directive *[equalTo]="password"* to link the validation to the original password field. 120 | - A custom validation directive called *[equalTo]* is implemented to compare the field value with the original password value. 121 | 122 | --- 123 | 124 | ### Reactive Forms (Model-Driven) 125 | 126 | Reactive forms offer greater control and flexibility. They are programmatically built, and validation is defined in the TypeScript code. 127 | 128 | Example: 129 | 130 | ```typescript 131 | import { Component } from '@angular/core'; 132 | import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 133 | 134 | @Component({ 135 | selector: 'app-example', 136 | template: ` 137 |
138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 |
146 | ` 147 | }) 148 | export class ExampleComponent { 149 | myForm: FormGroup; 150 | 151 | constructor(private formBuilder: FormBuilder) { 152 | this.myForm = this.formBuilder.group({ 153 | name: ['', Validators.required], 154 | email: ['', [Validators.required, Validators.email]] 155 | }); 156 | } 157 | 158 | submit() { 159 | if (this.myForm.valid) { 160 | // Logic to process the data 161 | } 162 | } 163 | } 164 | ``` 165 | 166 | **Code Details:** 167 | 168 | - **import { FormBuilder, FormGroup, Validators } from '@angular/forms';** - Importing necessary modules to build and validate the reactive form. 169 | 170 | - **constructor(private formBuilder: FormBuilder) { ... }** - The `FormBuilder` service is injected in the component's constructor to simplify the creation of the reactive form. 171 | 172 | - **this.myForm = this.formBuilder.group({ ... })** - Using `FormBuilder` to create a `FormGroup` named `myForm`, where fields and their validations are defined. 173 | 174 | - **name: ['', Validators.required]** - Defining the *"name"* field with an initial empty value (`''`) and applying a required field validation. 175 | 176 | - **email: ['', [Validators.required, Validators.email]]** - Defining the *"email"* field with an initial empty value and applying two validations: required field and valid email format. 177 | 178 | - **(ngSubmit)="submit()"** - Binding the form's *ngSubmit* event to the `submit()` method, which is called when the "Submit" button is pressed. 179 | 180 | - **submit() { ... }** - This method is called when the form is submitted. We check if the form is valid using `this.myForm.valid`. If valid, logic to process form data can be added. 181 | 182 | ```text 183 | Note: To work with reactive forms, you must import the `ReactiveFormsModule` in the `app.module.ts` file. 184 | ``` 185 | 186 | ### Validation in Reactive Forms (Model-Driven) 187 | 188 | **Required Field Validation (Reactive)** 189 | 190 | ```typescript 191 | import { Component } from '@angular/core'; 192 | import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 193 | 194 | @Component({ 195 | selector: 'app-example', 196 | template: ` 197 |
198 | 199 | 200 | 201 |
202 | Name is required. 203 |
204 | 205 | 206 | 207 | 208 |
209 | Enter a valid email. 210 |
211 | 212 | 213 |
214 | ` 215 | }) 216 | export class ExampleComponent { 217 | myForm: FormGroup; 218 | 219 | constructor(private formBuilder: FormBuilder) { 220 | this.myForm = this.formBuilder.group({ 221 | name: ['', Validators.required], 222 | email: ['', Validators.required] 223 | }); 224 | } 225 | 226 | submit() { 227 | if (this.myForm.valid) { 228 | // Logic to process the data 229 | } 230 | } 231 | } 232 | ``` 233 | 234 | Explanation: 235 | 236 | - We use *FormBuilder* to create a form group (*FormGroup*) named *myForm*. This group contains the form fields. 237 | - For the *"name"* field, we define a control with an initial empty value `''` and apply the required field validation (*Validators.required*). 238 | - Similarly, we do the same for the *"email"* field, applying the required field validation. 239 | 240 | **Email Format Validation (Reactive)** 241 | 242 | ```typescript 243 | this.myForm = this.formBuilder.group({ 244 | email: ['', [Validators.required, Validators.email]] 245 | }); 246 | ``` 247 | 248 | Explanation: 249 | 250 | - We create an *"email"* field within the *myForm* group. 251 | - An array of validators is used for this field. *Validators.required* ensures the field is filled, and *Validators.email* checks if the entered value is in a valid email format. 252 | 253 | **Min and Max Length Validation (Reactive)** 254 | 255 | ```typescript 256 | this.myForm = this.formBuilder.group({ 257 | password: ['', [Validators.required, Validators.minLength(6), Validators.maxLength(12)]] 258 | }); 259 | ``` 260 | 261 | Explanation: 262 | 263 | - We create a *"password"* field within the *myForm* group. 264 | - A series of validators is used for this field. *Validators.required* ensures the field is filled, *Validators.minLength(6)* checks if the password has at least 6 characters, and *Validators.maxLength(12)* checks if the password has at most 12 characters. 265 | 266 | **Field Comparison Validation (Password Confirmation) (Reactive)** 267 | 268 | ```typescript 269 | this.myForm = this.formBuilder.group({ 270 | password: ['', Validators.required], 271 | confirmPassword: ['', [Validators.required, this.equalToValidator('password')]] 272 | }); 273 | 274 | equalToValidator(otherControlName: string) { 275 | return (control: AbstractControl): { [key: string]: any } | null => { 276 | const otherControl = control.root.get(otherControlName); 277 | 278 | if (otherControl && control.value !== otherControl.value) { 279 | return { equalTo: true }; 280 | } 281 | 282 | return null; 283 | }; 284 | } 285 | ``` 286 | 287 | Explanation: 288 | 289 | - We create two fields, *"password"* and *"confirmPassword"*, within the *myForm* group. 290 | - For the *"confirmPassword"* field, we apply a custom validation *this.equalToValidator('password')*. This function compares the field value with the *"password"* field value. 291 | - The *equalToValidator* function returns a custom validator that compares the two field values. If they are different, the validation returns *{ equalTo: true }*, indicating the passwords do not match. 292 | 293 | **Custom Validation (Reactive)** 294 | 295 | ```typescript 296 | this.myForm = this.formBuilder.group({ 297 | username: ['', [Validators.required, this.customValidation]] 298 | }); 299 | 300 | customValidation(control: AbstractControl): { [key: string]: any } | null { 301 | if (control.value === 'admin') { 302 | return { customValidation: true }; 303 | } 304 | 305 | return null; 306 | } 307 | ``` 308 | 309 | Explanation: 310 | 311 | - We create a *"username"* field within the *myForm* group. 312 | - A custom validation *this.customValidation* is applied. This function checks if the entered value equals "*admin*". 313 | - If the value is "*admin*", the validation returns *{ customValidation: true }*, indicating a custom error. 314 | 315 | 316 | ## :orange_book: Angular documentation 317 | 318 | 319 | [See official Angular documentation with detailed information about Form Validation](https://angular.dev/guide/forms). 320 | 321 | 322 | ## 👷 Task 323 | 324 | Create pull requests for your project according to [Task Submission Guidelines.](../assessment.md#task-submission) 325 | 326 | - Create validation with Reactive Forms in inserting, and updating components of your model project in the previous task (15 services). 327 | 328 | You can use task [Insert component with form validation](https://github.com/persapiens-classes/account-frontend/issues/16) of the Angular Example Project. 329 | 330 | --------------------------------------------------------------------------------