diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b6aa1f1..fc2bedb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,12 +1,14 @@ name: Build Ionic Angular App -on: - push: - branches: - - main - pull_request: - branches: - - main +run-name: ${{ github.actor }} build Ionic Angular App +on: [push] +# on: +# push: +# branches: +# - main +# pull_request: +# branches: +# - main jobs: build: @@ -19,7 +21,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: 16 + node-version: 22 - name: Install dependencies run: npm install @@ -29,7 +31,8 @@ jobs: - name: Build the app run: ionic build - - - name: Run unit tests - run: npm test + + # does not work, Missing X server or $DISPLAY + # - name: Run unit tests + # run: npm test diff --git a/.github/workflows/github-actions-demo.yml b/.github/workflows/github-actions-demo.yml deleted file mode 100644 index 15a61d6..0000000 --- a/.github/workflows/github-actions-demo.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: GitHub Actions Demo -run-name: ${{ github.actor }} is testing out GitHub Actions πŸš€ -on: [push] -jobs: - Explore-GitHub-Actions: - runs-on: ubuntu-latest - steps: - - run: echo "πŸŽ‰ The job was automatically triggered by a ${{ github.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!" - - run: echo "πŸ”Ž The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}." - - name: Check out repository code - uses: actions/checkout@v4 - - run: echo "πŸ’‘ The ${{ github.repository }} repository has been cloned to the runner." - - run: echo "πŸ–₯️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ github.workspace }} - - run: echo "🍏 This job's status is ${{ job.status }}." diff --git a/AngularInterviewNotes.md b/AngularInterviewNotes.md new file mode 100644 index 0000000..7eff974 --- /dev/null +++ b/AngularInterviewNotes.md @@ -0,0 +1,400 @@ +# Angular Interview Notes + +- [Angular Interview Notes](#angular-interview-notes) + - [YARN](#yarn) + - [DRY](#dry) + - [SOLID](#solid) + - [Object Oriented Programming](#object-oriented-programming) + - [Playwright](#playwright) + - [Jasmine](#jasmine) + - [Accessibility](#accessibility) + - [Styling SCSS](#styling-scss) + - [How javascript works underneath the hoods](#how-javascript-works-underneath-the-hoods) + - [Async Code example](#async-code-example) + - [Change Detection on push](#change-detection-on-push) + - [Life Cycle Hooks](#life-cycle-hooks) + - [RxJS](#rxjs) + - [Hot And Cold Observables](#hot-and-cold-observables) + - [Signals](#signals) + - [RXjS Most Common](#rxjs-most-common) + - [Components or Directives](#components-or-directives) + - [NGRx (Global)](#ngrx-global) + - [NGRX Component Store](#ngrx-component-store) + - [Micro Frontend](#micro-frontend) + - [NX and Monorepo](#nx-and-monorepo) + - [Ionic Need To Know](#ionic-need-to-know) + - [Service Worker](#service-worker) + - [Standalone](#standalone) + - [AOT (Ahead of Time Compilation) and Just in time compilation](#aot-ahead-of-time-compilation-and-just-in-time-compilation) + - [Modules](#modules) + - [IndexDB](#indexdb) + - [ChangeDetectorRef](#changedetectorref) + - [Questions and Answers](#questions-and-answers) + - [Mock Interviews and Coding Practice](#mock-interviews-and-coding-practice) + +## YARN + +## DRY + +## SOLID + +Robust, scalable, and easier to maintain, leading to higher quality and more adaptable codebases. + +1. **Single Responsibility Principle (SRP)** + +- do one thing and do it well +- A class should have only one reason to change, meaning it should have only one job or responsibility. +- Understandable, easy to name and maintainable. + +1. **Open/Closed Principle (OCP)** + +- Software entities like classes, modules, and functions should be open for extension but closed for modification. +- This means you can add new functionality without altering existing code. polymorphism and abstraction. But difficult to change in order to protect from the developers mistakes + +1. **Liskov Substitution Principle (LSP)** + +- Objects of a superclass should be replaceable with objects of a subclass without affecting the correctness of the program. + +1. **Interface Segregation Principle (ISP)** + +- No client should be forced to depend on methods it does not use. +- **Have many specific interfaces than a single general-purpose one**. + +1. **Dependency Inversion Principle (DIP)** + +- **Depend on abstractions, not on concrete implementations**. +- High-level modules should not depend on low-level modules; both should depend on abstractions. + +## Object Oriented Programming + +- **Encapsulation**: + + - Use **private, protected and public** methods to expose outside components or classes only the necessary fields and methods + - This principle involves bundling related data and the methods that operate on that data within a single unit, such as a class. Encapsulation restricts external access to certain components of an object, promoting modularity and safeguarding data integrity. + +- **Abstraction**: + + - Expose **only essential features and hide unnecessary details**. Create an abstract class with contract (methods and fields) that are required and hide the implementation inside the concrete class + - For example **abstract http call logic inside service** + - **Declarative programming not imperative**, abstract the complex logic + - Abstraction focuses on exposing only the essential features of an object while hiding the complex details. By modeling classes pertinent to the problem, it reduces programming complexity and enhances code clarity. + +- **Inheritance**: + + - **Inherit methods fields from interfaces or classes from existing classes, hence do not repeat your self** + - Inheritance allows a new class (subclass or child class) to acquire properties and behaviors from an existing class (superclass or parent class). This mechanism promotes code reusability and establishes hierarchical relationships among classes. + +- **Polymorphism**: + - **It allows a single interface to represent different underlying data types, enhancing flexibility and integration in code**. + - We have one interface Leg and one more interface Human and Dog, both interfaces extend the Leg interface because they require the Leg interface fields. Later when we need to process the legs we can pass the Human or Dog interfaces as well. Essentially Human and Dog interfaces use polymorphism + - Derived from the Greek for "many forms," polymorphism enables methods or objects to take on multiple forms. + +## Playwright + +- An AI web browsing framework focused on simplicity and extensibility. +- + +## Jasmine + +## Accessibility + +Key Principles of Web Accessibility: + +- **Perceivable** visible, correct colors length of text +- **Operable** accessible from keyboard tabs for example +- **Understandable** self explanatory +- **Robust** Work on all screens for example + + **Perceivable**: Information and user interface components must be presentable to users in ways they can perceive. + **Operable**: User interface components and navigation must be operable; users should be able to interact with all controls. + **Understandable**: Information and the operation of the user interface must be understandable. + **Robust**: Content must be robust enough to be interpreted reliably by a wide variety of user agents, including assistive technologies. + +Best Practices for Implementing Accessibility: + + Use **Semantic HTML**: Employing proper HTML tags provides meaningful structure to your content, aiding assistive technologies in interpreting and navigating your site effectively. + + Ensure **Keyboard Accessibility**: Design interactive elements to be operable via keyboard alone, accommodating users who cannot use a mouse. + + Provide **Text Alternatives**: Offer descriptive alt text for images and transcripts for multimedia content, enabling screen readers to convey information to visually impaired users. + + Maintain **Sufficient Color Contrast**: Use color schemes with adequate contrast between text and background to assist users with visual impairments or color blindness. + + Implement ARIA Roles and Attributes: Utilize Accessible Rich Internet Applications (ARIA) specifications to enhance the accessibility of dynamic content and complex user interface components. + + Design Responsive Interfaces: Ensure your website adapts seamlessly to various devices and screen sizes, providing a consistent experience for all users. + + Conduct Regular Accessibility Testing: Use automated tools and manual testing methods to identify and address accessibility issues throughout the development process. + +## Styling SCSS + + Global Styles: + global.scss: apply globally, common elements, typography, and utility classes that are shared + Theming Variables: + variables.scss: src/theme/ directory, CSS variables that define the application's theme, such as colors, fonts, and spacing. + + Component-Level Styles: + Component SCSS Files component own SCSS file, enabling you to encapsulate styles specific to that component.modularity and prevents styles from unintentionally affecting other parts of the application. By default, these styles are scoped locally to the component. + +Best Practices for Structuring SCSS in Ionic Angular: + + Organize SCSS Files: Styles directory containing subfolders for mixins, functions, and partials. + Ionic Forum + + Importing Styles: Use the global.scss to import your organized SCSS partials. + + Utilize CSS Variables: leverages CSS variables extensively for theming. variables.scss file + +## How javascript works underneath the hoods + +- JavaScript needs a runtime such as a web browser or Node.js +- Is single-threaded, event-driven model. + +1. JavaScript Engine: executes the code. It processes the code line by line, converting it into machine-readable instructions. +2. Call Stack: JavaScript uses a call stack to manage function execution. + 1. When a function is invoked, it's added to the top of the stack. Once executed, it's removed, and the engine proceeds to the next function. +3. Event Loop and Callback Queue: For handling asynchronous operations (like setTimeout or fetching data), JavaScript utilizes an event loop. + 1. When such operations are initiated, they're offloaded, and their callbacks are placed in a queue. + 2. The event loop continuously checks the call stack; + 1. if it's empty, it pushes the next callback from the queue onto the stack for execution. + +This model allows JavaScript to perform non-blocking operations despite being single-threaded, enabling efficient handling of tasks like user interactions and network requests. + +### Async Code example + +```ts +console.log("Start"); //Synchronous Code Execution: JavaScript executes synchronous code first. Therefore, 'Start' is logged immediately. + +setTimeout(() => { + //the callback is placed in the macrotask queue + console.log("Timeout"); +}, 0); + +Promise.resolve().then(() => { + //placed in the microtask queue + console.log("Promise"); +}); + +console.log("End"); + +//result +// Start +// End +// Promise +// Timeout +``` + +1. synchronous excecutions Start and End +2. microtask que Promis.resolve().then() +3. macrotask que setTimeout() + +- **setTimeout** **macrotask queue** and will only **execute after the current execution stack is clear** and **all microtasks have been processed**. +- Promise.resolve().then(...): Promises' .**then()** handlers are placed in the **microtask** queue, which has a higher priority than the macrotask queue. executed immediately after the current synchronous code completes, before any macrotasks. +- **Microtask** Execution: Once the synchronous code is finished, the event loop checks the microtask queue and executes. +- **Macrotask** Execution: Once the synchronous code is finished and microtask is empty, the event loop will processes the macrotask + +## Change Detection on push + +Default, Angular's change detection strategy checks all components in the component tree for changes during each change detection cycle. lead to performance due to the extensive checks. + +To optimize performance, Angular provides the ChangeDetectionStrategy.OnPush strategy. When a component is configured with OnPush, Angular's change detection is triggered for that component only under specific conditions: + + Input Property Changes: If an @Input() property of the component receives a new reference (i.e., the reference changes, not just the properties of the object), Angular will trigger change detection for that component. + + Events Originating from the Component or its Children: User interactions such as clicks, input events, or other DOM events within the component or its child components can trigger change detection. + + Manual Invocation: Developers can manually trigger change detection by injecting the ChangeDetectorRef service and calling its markForCheck() or detectChanges() methods. + +## Life Cycle Hooks + +ngOnInit + + Called once after the first ngOnChanges. + Ideal for component initialization and fetching initial data. + +ngOnChanges + + Invoked when any data-bound input property changes. + Receives a SimpleChanges object containing current and previous property values. + +ngOnDestroy + + Called just before Angular destroys the component. + Perfect for cleanup tasks like unsubscribing from observables. + +ngAfterViewInit + + Runs once after the component's view and child views have been initialized. + +ngAfterContentInit + + Executed once after Angular projects external content into the component's view. + +ngAfterContentChecked + + Called after every check of projected content. + +ngAfterViewChecked + + Invoked after every check of the component's view and child views. + +ngDoCheck + + Runs during every change detection cycle. + Use for custom change detection logic. + +## RxJS + +- combine latest +- map +- concatMap +- switchMap +- mergeMap + +## Hot And Cold Observables + +Hot vs Cold Observables + +- Cold Observables start emitting when the subscription starts +- Hot Observables are always being updated with new values, + +## Signals + +- Signals are ideal for handling synchronous state changes, while observables excel in managing asynchronous events + +- set(newValue): Directly assigns a new value to the signal. + +const count = signal(0); +count.set(5); // Sets the signal's value to 5 + +- update(updaterFn): Updates the signal's value based on its current state by applying the provided function. + +const count = signal(0); +count.update(value => value + 1); // Increments the current value by 1 + +- mutate(mutatorFn): Applies a mutator function to modify the signal's value in place, useful for complex data structures. + +const items = signal(['apple', 'banana']); +items.mutate(list => list.push('cherry')); // Adds 'cherry' to the array + +- computed(computeFn): Creates a new signal whose value is derived from other signals. It automatically recalculates when any of its dependencies change. + +const width = signal(5); +const height = signal(10); +const area = computed(() => width() \* height()); +console.log(area()); // Outputs: 50 + +## RXjS Most Common + +- pipe: used to compose multiple operators into a sequence, you can create flexible and reusable data processing pipelines in a declarative manner. +- map: Transforms each value +- filter: values +- switchMap: Projects each source value to an Observable, which is merged in the output Observable, emitting values only from the most recently projected Observable +- mergeMap (also known as flatMap): Maps each value to an Observable, then flattens all of these inner Observables using mergeAll. It allows for concurrent inner subscriptions. +- concatMap: waits for the observable to finish and after it moves on to the next +- combineLatest: Combines multiple Observables to create an Observable whose value is calculated from the other. Does not start to emit until all have emitted and after it emits whenever one emits +- tap: Performs a side effect +- catchError: Catches errors on the source Observable and returns a new Observable or throws an error +- debounceTime: Delays the emissions of the source Observable by a given time span, and omits any intermediate values + +## Components or Directives + +- Components for new widgets +- Directives for new behavior logic to existing component or elements + - does not include HTML + - can add multiple directives on components or elements + +## NGRx (Global) + +## NGRX Component Store + + + +## Micro Frontend + +## NX and Monorepo + + + +Best Practices for Monorepos + + Use tools like Nx, Bazel, or Turborepo to optimize builds and testing. + Implement a robust CI/CD pipeline to handle incremental builds and selective testing. + Structure the repository to clearly separate projects and shared libraries. + Establish clear guidelines for dependencies and code ownership. + Use feature flags or versioned libraries to decouple updates across projects. + +When to Choose a Monorepo + + If you have tightly coupled projects with shared components. + When you aim to enforce consistent tooling, standards, and processes. + For organizations where collaboration between teams is a priority. + +When to Avoid a Monorepo + + If the projects are entirely unrelated and have no shared code. + When you lack the necessary tooling or infrastructure to manage a large monorepo effectively. + If granular access control is a critical requirement. + +## Ionic Need To Know + +## Service Worker + +- Its a script that runs in the background of your web browser +- It acts as a programmable network proxy, to intercept and control how network requests are handled + - used for creating Progressive Web Apps (PWAs) that offer offline support + - caching assets and responses enable web applications to work even when the network is unavailable + - They can synchronize data in the background, ensuring that the latest updates are available when the user reconnects to the internet. +- Capabilities like push notifications. + +## Standalone + +Enables treeshaking so the final build output only includes the code necessary to run your app which reduces overall build size. +Avoids the use of NgModules to streamline the development experience and make your code easier to understand. +Allows developers to also use newer Angular features such as ESBuild. + +## AOT (Ahead of Time Compilation) and Just in time compilation + +- more performance no need to transpile code in run time +- helps to catch errors, is more strict +- prepare everything before we release to production and just ship everything as js files, no template or ts file + +## Modules + +- imports + - other modules +- declarations + - define module components +- export + - export defined modules if necessary +- providers + - services + +## IndexDB + +- + +## ChangeDetectorRef + +https://angular.dev/api/core/ChangeDetectorRef + +## Questions and Answers + +1. +2. +3. +4. +5. +6. +7. +8. +9. + +## Mock Interviews and Coding Practice + +- Interview Platforms: + - Pramp: Offers free mock interviews with peers to practice coding and system design. + - Interviewing.io: Provides mock interviews conducted by experienced software engineers. +- Coding Challenges: + - HackerRank: Features a variety of coding challenges, including those focused on Angular. + - LeetCode: Offers a vast collection of coding problems to enhance problem-solving skills. diff --git a/Backend/README.md b/Backend/README.md new file mode 100644 index 0000000..1a5fa81 --- /dev/null +++ b/Backend/README.md @@ -0,0 +1,119 @@ +# Go + +- [Go](#go) + - [Notes](#notes) + - [Run Go File For Development](#run-go-file-for-development) + - [Build](#build) + - [Double Quotes, Single Quotes and Backticks](#double-quotes-single-quotes-and-backticks) + - [Package Clause](#package-clause) + - [main Package](#main-package) + - [main Function](#main-function) + - [Modules](#modules) + - [Math Operations](#math-operations) + - [Go Types \& Null Values](#go-types--null-values) + +## Notes + +### Run Go File For Development + +go run + +### Build + +- creates executable file +- `go build` (requires a module to work `go mod init `) + - on windows it simply creates a .exe file + - the `package main` is necessary to build because go needs to know the starting point of the application + + +### Double Quotes, Single Quotes and Backticks + +In go Double quotes and backticks are used for strings + +### Package Clause + +- Each peace of GO code need to belong into a Package. and hence this is why the package statement is necessary as the firs statement of each file +- similar to projects or libraries + +#### main Package + +- special package that tells go which is the main entry point of our application + +### main Function + +- main function is the function that go will call when the program starts +- it is the root of the app and must be unique in the whole app +- if you want to create a package and export it you should not have a main function + +### Modules + +- A module is simply a go project +- Create a module + - `go mod init ` + +### Math Operations + +- we cannot apply operations of different types, either use int or float64 + +```go +package main + +import ( + "fmt" + "math" +) + +func main() { + var valueA float64 = 10 + valueB := 2.2 + valueC, valueD := 2.2, 6.6//tells go to infer the type + var test = math.Pow(10, valueA * valueB * valueC * valueD) + fmt.Println(test) +} +``` + +### Go Types & Null Values + +Basic Types + +Go comes with a couple of built-in basic types: + + int => A number WITHOUT decimal places (e.g., -5, 10, 12 etc) + + float64 => A number WITH decimal places (e.g., -5.2, 10.123, 12.9 etc) + + string => A text value (created via double quotes or backticks: "Hello World", `Hi everyone') + + bool => true or false + +But there also are some noteworthy "niche" basic types which you'll typically not need that often but which you should still know about: + + uint => An unsigned integer which means a strictly non-negative integer (e.g., 0, 10, 255 etc) + + int32 => A 32-bit signed integer, which is an integer with a specific range from -2,147,483,648 to 2,147,483,647 (e.g., -1234567890, 1234567890) + + rune => An alias for int32, represents a Unicode code point (i.e., a single character), and is used when dealing with Unicode characters (e.g., 'a', 'Γ±', 'δΈ–') + + uint32 => A 32-bit unsigned integer, an integer that can represent values from 0 to 4,294,967,295 + + int64 => A 64-bit signed integer, an integer that can represent a larger range of values, specifically from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 + + There also are more types like int8 or uint8 which work in the same way (=> integer with smaller number range) + +Null Values + +All Go value types come with a so-called "null value" which is the value stored in a variable if no other value is explicitly set. + +For example, the following int variable would have a default value of 0 (because 0 is the null value of int, int32 etc): + + var age int // age is 0 + +Here's a list of the null values for the different types: + + int => 0 + + float64 => 0.0 + + string => "" (i.e., an empty string) + + bool => false diff --git a/Backend/app.go b/Backend/app.go new file mode 100644 index 0000000..f6d8eb6 --- /dev/null +++ b/Backend/app.go @@ -0,0 +1,14 @@ +package main + +import ( + "fmt" + "math" +) + +func main() { + var valueA float64 = 10 + valueB := 2.2 + valueC, valueD := 2.2, 6.6 + var test = math.Pow(10, valueA * valueB * valueC * valueD) + fmt.Println(test) +} diff --git a/Backend/exampleModulePath.exe b/Backend/exampleModulePath.exe new file mode 100644 index 0000000..dcbcd40 Binary files /dev/null and b/Backend/exampleModulePath.exe differ diff --git a/Backend/go.mod b/Backend/go.mod new file mode 100644 index 0000000..22560e0 --- /dev/null +++ b/Backend/go.mod @@ -0,0 +1,3 @@ +module exampleModulePath + +go 1.23.4 diff --git a/README.md b/README.md index 1cc730b..538e231 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,4 @@ Simple Ionic PWA example App using Angular 19. This could serve as an example st - Add BE with websockets for logs - fix unit tests - Add acceptance tests (end to end) +- Accessibility decorators diff --git a/package.json b/package.json index dd7e414..df9b128 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "ng": "ng", "start": "ng serve", - "build": "ng build", + "build": "ng build --verbose", "watch": "ng build --watch --configuration development", "test": "ng test", "lint": "ng lint"