Coder Social home page Coder Social logo

learnings's People

Contributors

prawin-s avatar

Watchers

 avatar

learnings's Issues

Github : Steps to change default branch from master to main

# Step 1 
# create main branch locally, taking the history from master
git branch -m master main

# Step 2 
# push the new local main branch to the remote repo (GitHub) 
git push -u origin main

# Step 3
# switch the current HEAD to the main branch
git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/main

# Step 4
# change the default branch on GitHub to main
# https://docs.github.com/en/github/administering-a-repository/setting-the-default-branch

# Step 5
# delete the master branch on the remote
git push origin --delete master

Angular Commands

Angular upgrade @angular 10 to 11 -

Approach 1 - Update Angular CLI:
You can directly upgrade your angular cli version globally by using update command of ng as below -

ng update @angular/cli @angular/core

Now you can see ng version by following command:

ng version

Approach 2 - Update Angular CLI using reinstall

Angular Material : In Progress

Angular CLI -

Angular CLI is a command line interface for Angular. It makes it easy to create an application that already works right out of the box.


Globally Install NodeJS & Install TypeScript

npm install -g typescript
npm install -g [email protected]

To check installed TS version-
tsc --version


npm install -g @angular/cli

Command to uninstall CLI-
npm uninstall -g @angular/cli

Command to uninstall old cli version-
npm uninstall -g angular-cli

Command to install specific version -
npm install -g @angular/[email protected]

Check Version -
ng --version

Add Angular Material -
ng add @angular/material

Install specific version -
ng add @angular/[email protected]


ng new angularmaterial
cd angularmaterial
ng serve

State management with NgRx : 3 Short Principles

Following three short principles are the foundation for state management with NgRx:

Single Source of Truth: The application state is stored in one object

State is Read-Only: You cannot change the current state, only dispatch an action and produce a new state.

Changes are made with pure functions: The next state is produced purely based on the current state and a dispatched action - no side-effects allowed

Together these principles make sure that state transitions are explicit and deterministic, meaning you can easily tell how the application state evolves over time.

Action, State & Reducer :

Action
Actions are plain JavaScript objects that reference events occurring in the application. Actions are distinguished by a type but can have arbitrary more properties to serve as a payload containing information about a corresponding event.

State
A plain JavaScript object holds the global application state.

Reducer
A reducer is a pure function that takes the current state and an action as parameters while returning the next state.

Where Does NgRx Store Data?
NgRx stores the application state in an RxJS observable inside an Angular service called Store. At the same time, this service implements the Observable interface. So, when you subscribe to the store, the service actually forwards the subscription to the underlying observable.

Internally, NgRx is actually using a BehaviorSubject which is a special observable that has the following characteristics:

  • new subscribers receive the current value upon subscription
  • it requires an initial value
  • since a BehaviorSubject is in turn a specialized Subject you can emit a new value on it with subject.next()
  • you can retrieve its current value synchronously using subject.getValue()

How NgRx Effects Works?
NgRx effects are managing asynchronous side-effects with RxJS observables resulting in actions being dispatched to the store. Since reducers are pure functions, they can't have side-effects - so things like HTTP requests aren't allowed. However, actions can be dispatched at anytime, for example as the result of an HTTP request that saves a data to the server.

NGRX Book Tips : Angular Performance Optimization

When memoizing selectors you’re trading memory for computation resources. Caching the result of a selector function means we don’t have to re-calculate it all the time. That’s a powerful technique, especially for a single-threaded language like JavaScript. Therefore you should leverage selector memoization when you need to transform the state before making it available to consumers. Remember to reset selectors when their results are no longer required.

One more interesting detail: Angular event bindings (i.e. calling a class method from the template) will block the change detection until the handler code completes. With NgRx we’re mostly just dispatching an action in order to then directly return the control flow to Angular. This way the view stays responsive while state transitions take place “in the background”.

  1. OnPush Change Detection

Angular has two strategies for detecting changes to the component state that need to be rendered into the view. There’s a default one which triggers all the time if anything changes. That’s not inherently bad and Angular, by default, delivers decent performance. Running the change detection less often still provides potential for improvement and that’s why the OnPush strategy also exists. It’ll trigger only in the following three cases:

  1. when a component’s inputs are reassigned
  2. when events occur on a component or one of its children
  3. when a component is dirty, meaning it’s explicitly marked for change detection through a call to markForCheck() on a ChangeDetectorRef (like it’s done inside of the AsyncPipe )

You can configure a component to use OnPush change detection by specifying the changeDetection metadata property in its decorator.

  1. Tracking List Elements

When rendering lists with the NgFor directive, Angular replaces DOM elements once the underlying object reference changes. In order to help the framework to optimize this process, you can provide a function for re-identifying elements with trackBy . While shallow copying won’t change too many object references at the same time, you can still benefit from applying this optimization, especially for transient elements produced from selector projectors.

  1. Efficient Handling of Remote Data

Try not to replicate your whole database on the client-side by fetching everything into the store. Keep the amount of cached data reasonable and try to clear parts that aren’t used anymore.

Code Snippet : Using Behavior Subject for lookups

//Using behaviour subject  to store a different lookup list dynamically inside Object
import { Injectable } from "@angular/core";
import { BehaviorSubject, of } from "rxjs";

export interface ILookup {
    id: string | number;
    value: any;
}

@Injectable({ providedIn: "root" })
export class LookupService {
    private _lookups: { [key in string]: BehaviorSubject<ILookup[]> } = {};

    initlizeLookup(key: string) {
        if (!this._lookups[key]) {
            this._lookups[key] = new BehaviorSubject([]);
        }
        return this._lookups[key];
    }

    getLookup(key: string) {
        return this._lookups[key] || this.initlizeLookup(key);
    }

    getLookupValue(key: string) {
        return this.getLookup(key).getValue();
    }

    loadLookup(key: string) {
        // assume you have api to retrieve lookup like list of countries,..., etc
        // return this.http(url)
        // .pipe(map(res=> {
        //  if( res?.data[key]){
        //    this.getLookup(key).next(re.data[key]);
        // }
        // }))
        // i will hardcode the response of titles
        this.getLookup("titles").next([
            { id: "Mr", value: 1 },
            { id: "Mrs", value: 2 },
            { id: "Miss", value: 3 },
            { id: "Prof", value: 4 }
        ]);
        return of(true);
    }
}

Typescript Tips

TypeScript tip (1):

TypeScript infers array's type as an Array of the union of included types... which may not be precise enough.

If you want this value to be inferred as a Tuple instead, add as const

Example :
Existing code -

function getDemo() {
    let title = 'A demo'
    let index = 1

    return [title, index]
}
const demo = getDemo();
const val1 = demo[0];
const val2 = demo[1];

New Code -

function getDemo1() {
    let title = 'A demo'
    let index = 1

    return [title, index] as const
}

const demo1 = getDemo1();
const val11 = demo1[0];
const val21 = demo1[1];

StackBlitz Link : https://stackblitz.com/edit/return-as-const?file=index.ts

TypeScript tip (2):

Sometimes you need to access something custom on the window object… and TypeScript complains.

Instead of throwing as any at it – and losing type safety!
–describe your global thing as a part of the Window interface in a d.ts file!

One Approach (use as any)- File : index.ts

(window as any).runMyStuff()

Better Approach - File : index.d.ts

export { }

declare global {
    interface window {
        runMyStuff: () => void
    }

}

File : index.ts
window.runMyStuff()


TypeScript tip (3):

When working with a directory-like object, typing it as strictly as possible helps to prevent bugs and improve maintainability.

You can use the index signature for that… but the built-in Record<Keys, Values> is way more straightforward!

type Color = 'primary' | 'secondary'

type Theme = Record<Color, string>

const themes: Theme = {
    primary: '#ccc',
    secndary: '#ddd'
}

Error - Type '{ primary: string; secndary: string; }' is not assignable to type 'Record<Color, string>'.
Object literal may only specify known properties, but 'secndary' does not exist in type 'Record<Color, string>'.
Did you mean to write 'secondary'?

StackBlitz Link : https://stackblitz.com/edit/ts-record?file=index.ts


TypeScript tip (4):

Keeping your objects immutable is often important for

  • performance (e.g. Redux or onPush in @angular)
  • and sane logic (e.g. don't wanna mutate default values)

You can make your object read-only (nested!) by adding as const assertion:

const defaultConfig = {
    initialQuery: 'Jake',
    pagination: {
        enabled: true,
        items: 10
    }
} as const

defaultConfig.pagination.items = 11

Error - Cannot assign to 'items' because it is a read-only property

StackBlitz Link : https://stackblitz.com/edit/ts-obj-as-const?file=index.ts


TypeScript tip (5):

The keyof operator extracts the keys of a given type, which makes it extremely useful
for all kinds of logic that's based on properties of an object – like sorting, filtering, etc.

Combine it with a generic type to make it more universal!

Example -


interface User {
    name: string
    age: number
    points: number
}

const users: User[] = []
const books = [{ title: 'TypeScript' }]

function sortBy<T>(items: T[], prop: keyof T) {
    return // todo: implement sorting;)
}

sortBy(users, 'age')
sortBy(books, 'title')

StackBlitz Link - https://stackblitz.com/edit/ts-keyof?file=index.ts


#TypeScript tip:

"Nullish coalescing operator" sounds intimidating, but it's simply a handy way of providing a fallback in case of undefined or null value.

Typescript 3.7 introduced Nullish coalescing (??) operator
which allows to get a fallback for 'null' and 'undefined'

const user1 = auth.username ? auth.username : 'Anonymous'

const user2 = auth.username ?? 'Anonymous'

Important Note : It is not a 1:1 replacement of a ternary operator
Won't return fallback for '""', '0' , 'NaN' or 'false'


TypeScript tip (6):

If your function/class will work with multiple types but they need to meet some minimal criteria,
you can specify the minimal shape a generic must have by extending it:

<T extends MyBaseType>

Example :

**function store<T extends { id: number }>(item: T) {
console.log(saving ${item.id})
}

const book = { id: 1, title: '' }
store(book)

store({ id: 32, email: '' })

store(new Date())
store(123)
store('XYZ')**


TypeScript tip (7):

Using the built-in Partial<T> you can create a new type with all the properties of your base type () set to optional – useful for update logic and writing tests.

The opposite is Required<T>, which makes all the properties, well, required

type User = {
  id: number
  username: string
  nickname?: string
}

type UserUpdate = Partial<User>
let update: UserUpdate = {}

type FullUser = Required<User>
let fullUser: FullUser = {}


TypeScript tip (8):

If you want to make sure no-one mutates your array, make it readonly:

type Role = 'admin' | 'editor' | 'user'

const roles: readonly Role[] = ['editor', 'user']

roles.push('admin')
roles.concat(['admin'])

roles.splice(0, 1)
roles.slice(0, 1)

roles[1] = 'admin'
console.log(roles[1])

Cloning JS Objects

Cloning Objects:

It is possible to create a shallow copy and a deep copy of an object. A shallow copy of an object references the original. So any changes made to the original object will be reflected in the copy. A deep copy is a copy of all elements of the original object. Changes made to the original object will not be reflected in the copy.

Deep copies of the objects can be created using the Lodash Library.

Ways to create Shallow copies -

  1. Create Shallow Copy by Reassigning Object
    Reassigning objects to new variables only creates a shallow copy of the original object.

  2. Create Shallow Copy by Looping Through Object

Important things to note :

  • A loop that copies each property to a new object would only copy enumerable properties on the object. Enumerable properties are properties that will show up in for loops and Object.keys.
  • The copied object has a new Object.prototype method, which is not what you want when you copy an object. This means that whatever changes you make to the original object will be reflected in the copied object.
  • If your object has a property that is an object, your copied object will actually refer to the original instead of creating an actual copy. This means that if you change that nested object in the copied object, the original gets changed as well.
  • Any property descriptors are not copied. If you set things like configurable or writable to false, the property descriptors in the copied object will default to true.

Looping through objects allows you to create shallow copies, but it isn’t possible to create deep copies using this method.

  1. Creating Shallow and Deep Copies Using Lodash

For simple objects that only store primitive types like numbers and strings, shallow copying methods like the one above will work. However, if your object features references to other nested objects, the actual object won’t be copied. You would only be copying the reference.

For a deep copy, one great option is to use reliable external libraries like Lodash. Lodash is a library that offers two different functions that allow you to do shallow copies and deep copies. These are clone and clonedeep.

  • You can create a shallow copy by using the Lodash clone function
  • You can create a deep copy by using the Lodash clonedeep function

Conclusion :

You can create shallow copies of objects by reassigning and looping through objects. You can also use the Lodash library to create both shallow and deep copies of objects.

Important Links :

POSTMAN : Working with SSL Certificates

Postman provides a way to view and set SSL certificates on a per domain basis -

  1. To manage your client certificates, click the wrench icon on the right side of the header toolbar, choose "Settings", and select the Certificates tab.

  2. To add a new client certificate, click the Add Certificate link.

  3. In the Host field, enter the domain (without protocol) of the request URL for which you want to use the certificate. Port number is optional and default will be used if nothing passed.

  4. Choose your client certificate file based on the format. Example - Select PFX format for PFX file.

  5. If you used a passphrase while generating the client certificate, you’ll need to supply the passphrase in the Passphrase field. Otherwise, leave it blank.

  6. Make sure SSL verification is ON in settings tab.

Code Snippet : AuthInterceptor

// - Get accessToken and accessTokenExpiry
// - Attempt to refresh if accessToken expired
// - Attempt to refresh once if a request returns 401
// - Handle 401 when all have failed -> force logout ->redirect to login
// - Handle 403 -> redirect to not authorized

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
    private allowed = ['/token/refresh', '/assets'];

    constructor(
        private readonly authStateService: AuthStateService,
        private readonly authService: AuthService,
        private readonly redirectService: RedirectService,
    ) { }

    private static addToken(req: HttpRequest<unknown>, token: unknown) {
        return req.clone({
            headers: req.headers.set('Authorization', `Bearer ${token}`),
        });
    }

    private refreshToClonedRequest(req: HttpRequest<unknown>, next: HttpHandler) {
        return concat(
            this.authService.refreshToken(),
            this.newTokenToClonedRequest(req, next),
        );
    }

    private newTokenToClonedRequest(
        req: HttpRequest<unknown>,
        next: HttpHandler,
    ) {
        return this.authStateService.token$.pipe(
            mergeMap((newToken) =>
                next.handle(AuthInterceptor.addToken(req, newToken)),
            ),
        );
    }

    intercept(
        request: HttpRequest<unknown>,
        next: HttpHandler,
    ): Observable<HttpEvent<unknown>> {
        if (this.allowed.some((url) => request.url.includes(url))) {
            // Allowed URLs do not need bearer token
            return next.handle(request);
        }

        let hasRetried = false;
        return combineLatest([
            this.authStateService.token$,
            this.authStateService.tokenExpiry$,
        ]).pipe(
            take(1),
            mergeMap(([token, expiry]) => {
                if (!token) {
                    // No token, just forward the request
                    return next.handle(request);
                }

                const cloned = AuthInterceptor.addToken(request, token);
                return defer(() => {
                    if (expiry && moment().isAfter(expiry)) {
                        return this.refreshToClonedRequest(request, next) as Observable<
                            HttpEvent<unknown>
                        >;
                    }

                    return next.handle(cloned).pipe(
                        retryWhen((errObs) =>
                            errObs.pipe(
                                mergeMap((err: SwaggerException) => {
                                    if (err.status === 401 && !hasRetried) {
                                        hasRetried = true;
                                        return this.refreshToClonedRequest(
                                            request,
                                            next,
                                        ) as Observable<HttpEvent<unknown>>;
                                    }
                                    return throwError(err);
                                }),
                            ),
                        ),
                    );
                }).pipe(
                    catchError((err) => {
                        if (SwaggerException.isSwaggerException(err)) {
                            if (err.status === 401) {
                                this.authService.logout().subscribe({
                                    complete: () => {
                                        this.redirectService.redirectToLogin();
                                    },
                                });
                            } else if (err.status === 403) {
                                this.redirectService.redirectToNotAuthorized();
                            }
                        }

                        return throwError(err);
                    }),
                );
            }),
        );
    }
}

Dell : Win 10 Re-install steps

  1. Download Recovery Tool -
    https://www.dell.com/support/home/en-us/drivers/osiso/recoverytool

  2. Launch OS Recovery Tool and follow steps as needed

  3. Complete all the steps

  4. Safely remove USB Drive

  5. Connect USB drive to device which needs RESET

  6. Turn on and press F12 continuously

  7. On Boot window -> Select UEFI BOOT -> Select UEFI option

  8. Select 'Reset' option from RESET section

  9. Select Reset option -> Reset and update

  10. Back up your files

  11. Confirm you reset : Select checkbox

  12. Select Drive : Location you would like to reset system

  13. Reset and update in progress

Angular : Patterns

  1. Container and Presentational Components

There’s this architectural concept in UI development where you separate components into the following two categories:
Presentational Components (aka dumb components) are purely concerned with looks. They don’t maintain state, depend on services or perform computations. They just render their template inputs into the view and emit events based on user interaction. These constraints allow them to be reusable and easily tested. Consequently, you wouldn’t inject the store into a presentational component. This way, it’s loosely coupled to the application logic and you can easily change where the underlying state is managed. Usually, presentational components also only contain other presentational components.

Container Components (aka smart components) are organizational wrappers around presentational or other container components. They deal with services and business logic, may contain state, but don’t really care that much for how things look. While dependency injection still allows for some loose coupling, container components are generally less-likely to be reused. They select state from the store in order to forward the data to presentational components via input bindings. Upon user interaction, the presentational components notify the containers via event emission which in turn will dispatch actions to the store.

  1. Facades
    The facade pattern is not specific to NgRx, Angular or even web development. It’s a general software design pattern originating from object-oriented programming. The idea is this: when you’re connecting a unit of code to one or more distinct units, instead of letting those interact directly you’re defining a clear boundary: a facade. By masking how things work on the other side, you prevent different concerns from leaking into each other. Eventually, a facade is an abstraction that’s meant to hide complexity.
    The facade pattern is not specific to NgRx, Angular or even web development. It’s a general software design pattern originating from object-oriented programming. The idea is this: when you’re connecting a unit of code to one or more distinct units, instead of letting those interact directly you’re defining a clear boundary: a facade. By masking how things work on the other side, you prevent different concerns from leaking into each other. Eventually, a facade is an abstraction that’s meant to hide complexity.

  2. Re-Hydration
    It’s a common requirement: persisting NgRx state in order to load it back up when the application is restarted. This process of populating an empty object with domain data is called re-hydration.
    There are some pitfalls to watch out for when applying this pattern. For one thing, you should take care not to store sensitive data in potentially insecure storages. Consider factors such as multiple users working on the same machine. Additionally, the state you’re storing can become outdated. Consequently, you might incorporate techniques like validation and partial re-hydration.

The popular approach for implementing re-hydration is based on meta-reducers. Such a re-hydration meta-reducer would have to do two things:

  1. Persist the resulting state after each action has been processed by the actual reducer(s)
  2. Provide persisted state upon initialization

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.