All posts by admin

Extends (typescript)

Let’s define a base class Person that takes in a parameter name, and assigns it to a protected property.

We then create Employee that extends from Person. It has a super reference to its parent class Person. Since it extends from Person, it can access property name. In our constructor, we simply take in a name and append a Emp stamp on it. We also override the work function from parent class.

When we declare functions, we can use the base class as parameters and pass in any kind of children classes. This is called Sharing common behavior

Abstract classes

Abstract classes requires children classes to implement abstract interface.

If you extend an abstraction and do not implement it, you’ll get compiler errors:

Unlike concrete classes, abstract classes cannot be instantiated.

Hence, in order to use it

The thing about extends from either concrete/abstract classes is that it satisfies several SOLID principles:

Liskov Substitution Principle

“Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.”

Since we define valid subtypes, each implementation should work and be interchangeable as long as it implements the contract. In our case, each implementation (Employee, Manager..etc) should work and be interchangeable with parameter Person because we implement the contract.

As long as our implementation extends from our base class, any pointers or reference to base class can use our derived classes.

Dependency Inversion Principle (DIP) – Depends upon abstraction, not concretion

instead of doing:

We can make call its abstraction instead:

  • Dependency upon abstraction – Don’t depend on the concrete implementation. Rather, depend on abstraction.
  • Liskov Principle – functions with base class reference shall be able to use extended classes

plays into Open Closed Principle.

Let’s say we want to create a function that calculates the area of an array of shapes. With our current design, it might look like that:

The issue with the above approach is that when we introduce a new shape, we need to modify our calculateAreasOfMultipleShapes function. This makes it open for modification and breaks the open-closed principle.

Now that we are sure that all of our shapes have the getArea function, we can use it further.

Now when we introduce a new shape, we don’t need to modify our calculateAreasOfMultipleShapes function. We make it open for extension but closed for modification.

Deep Copying objects using JSON stringify and parse

Serialize and De-serialize

ref – https://dev.to/nas5w/js-fundamentals-object-assignment-vs-primitive-assignment-5h64

One method that can be used to deep copy an object is to serialize and de-serialize the object. One common way to do this is using JSON.stringify and JSON.parse.

However, it does not work on function objects:

ref – https://stackoverflow.com/questions/18089033/json-stringify-does-not-process-object-methods

fetching data from remote server

ref – https://javascript.plainenglish.io/from-fetch-api-to-useeffect-and-axios-the-many-ways-of-fetching-api-data-367757ea5ac6

fetch( ) — the Fetch API method

A few months ago, I was primarily fetching data in JavaScript and React using the fetch() API. It’s the easiest, and most readily available way to get data, since it is built into most modern browsers (with exception of Internet Explorer as of me writing this blog).The fetch() API

It calls the fetch() method, which takes in one argument, the resource. This is the path to the data you want to fetch. This can be your API data such as a link, or a request object. It then returns a promise, which contains a response object. Since the response that we get back is just an HTTP response, we append the json() method to the response, so that we get back the actual JSON formatted data as our response.

On a side note, a major disadvantage of the fetch API is handling errors.

In my example above, I didn’t factor my code to handle errors. And this can be bad, because even if the url sends me an 404 error (meaning page not found), we still send that as a response without breaking our code. I will show you how to handle fetch errors in the next two methods below.

fetch with useEffect

Since hooks are becoming more common in how we use React, the hooks way of fetching data is using the useEffect method. The Effect Hook adds the ability to do the same function as componentDidMount in our first example, or to perform other side effects, but in a function component.

As the example above shows, we used a class component. The useEffect() lets us use componentDidMount, componentDidUpdate, componentDidUnmount that we would in classes, in function components, but it’s all packaged into a single API — useEffect!

If our response is okay, we go ahead and return that response. However, if our response isn’t okay, say there’s an error in our response, we throw the response as an error, that our .catch callback will handle.
Then in the .finally callback, we use it as a function that will show us our data or an error, should our response be okay or not.

Axios

Axios is an open-source library for making data requests. In order to use axios, you have to first install it as it does not come built in like fetch or useEffect in React. You can install it with package managers like yarn or npm.

Axios supports all modern browsers, even Internet Explorer.
You can also use it in vanilla JavaScript, React, Vue.js, and Angular.

Axios also has better error handling and performs automatic transformations. It lets us cut down a lot of our code!

We were able to cut down the response because Axios handles the first callback where we check to see if a response is okay and give us an error if it’s not.

Interface vs Type (typescript)

ref – https://pawelgrzybek.com/typescript-interface-vs-type/

Interfaces are restricted to an object type

Interface declarations can exclusively represent the shape of an object-like data structures. Type alias declarations can create a name for all kind of types including primitives (undefined, null, boolean, string and number), union, and intersection types. In a way, this difference makes the type more flexible. In theory every type declaration that you can express with an interface, you can recreate using a type alias. Lets have a look at an example that can be represented using a type alias but is beyond the power of an interface.

You can merge interfaces but not types

Multiple declarations with the same name are valid only when used with interface. Doing so doesn’t override previous one but produces a merged result containing members from all declarations.

Type aliases can use computed properties

The in keyword can be used to iterate over all of the items in an union of keys. We can use this feature to programmatically generate mapped types. Have a look at this example using type aliases.

Unfortunately we cannot take advantage of computed properties in an interface declaration.

resolution of both (types and interfaces) happens in the same phase. No more circular references

Example

Solution is we need to make sure axiosGet returns at least a subset of properties that matches type GetUsersResponse.
In our case, it is data: User[]

mixins and merging (multiple extends in typescript)

ref – https://www.digitalocean.com/community/tutorials/typescript-mixins
https://www.typescriptlang.org/docs/handbook/mixins.html#alternative-pattern

Limitations of Classes

Typescript classes can only extend ONE class

Let’s create an example so that we can demonstrate the value of mixins.

Consider two classes, Car and Lorry, which contain the drive and carry methods respectively.
Then, consider a third class called Truck.
A Truck should include both drive and carry methods:

This will not work because we can only extend a single class.

error: Classes can only extend a single class

1) interfaces can extend multiple classes in TypeScript

When an interface extends a class, it extends ONLY the class members but not their implementation because interfaces don’t contain implementations.

2) Declaration merging

When two or more declarations are declared with the same name, TypeScript merges them into one.

By leveraging these two functionalities in TypeScript, we can create an interface with the same name as Truck and extend both the Car and Lorry classes:

Due to declaration merging, the Truck class will be merged with the Truck interface. This means that the Truck class will now contain the function definitions from both Car and Lorry classes.

And here’s how it’s used:

We can now access the methods in Car and Lorry from a truck object.

Full Example

partialRight + lodash

declare a function:

we give our function to partialRight, along with
the parameter that goes on the right side.

Then use the partial function:

Ricky, Good Morning!

Notice we gave two parameters in the partialRight. This means we already decided that other two parameters (message, extra) have already been dictated when we call partialRight.

Therefore, we have already decided that when using the partial function, we only take ONE parameter (name).

Of course we can change this to only providing the third parameter, and having the user provide two parameters for the partial function.

ricky, Good Morning???

Assertion Operator – typescript

It is a way to tell the compiler

“this expression cannot be null or undefined here, so don’t complain about the possibility of it being null or undefined.”

Sometimes the type checker is unable to make that determination itself.

The bang operator tells the compiler to temporarily relax the “not null” constraint that it might otherwise demand. It says to the compiler: “As the developer, I know better than you that this variable cannot be null right now”.

“Just throw in an exclamation mark to make the code compile” is not very good advice.

The null assertion operator is not one to be used lightly as it is very easy to abuse in ways that will either hide bugs or cause them.

Optional chaining is better when you are trying to call a nested function because it will simply do nothing if something is undefined along the way.

Whereas assertion operator will result in an error being thrown.

Null assertion operators should only ever be used when you know for a fact that a variable could not possibly be null or undefined.

If there’s a chance that that is not the case, do the null check.

Example usage:

When Test’s data property is undefined, we get runtime error. When it is defined, we get “hohoho”.

Optional – typescript

ref – https://www.becomebetterprogrammer.com/typescript-question-mark/

A property can either have a value based on the type:
defined
or
undefined

A key difference here:

When using optional, the property is literally optional. We don’t even need to declare it.

If we were to do use value | undefined, the value may either exist or be undefined, but we MUST make sure the property is there:

Example Usage:

say if we declare null for Test’s datq property:

useEffect

ref – https://www.glennstovall.com/how-to-use-useeffect-and-other-hooks-in-class-components/
https://stackoverflow.com/questions/58579426/in-useeffect-whats-the-difference-between-providing-no-dependency-array-and-an

The first two arguments of useEffect are a function (didUpdate), and an array of dependencies. the didUpdate function can return a function of its own, a cleanUp function. When a component mounts or the dependencies are updated, didUpdate is called. When the component unmounts, cleanUp is called if present.

In React, functional component use useEffect in order to do something “A” when that component has finished rendering its DOM. This is our subscribing effect. React guarantees the DOM has been updated by the time it runs the effects.

Every time we re-render, we schedule a different effect, replacing the previous one.

React cleans up effects from the previous render before running the effects next time.
And the next effect happens when our components update.

By declaring the dependencies array as empty, you only call the didUpdate and cleanUp functions once each. No dependencies mean no updates.

It simply means that the hook will only trigger once when the component is first rendered. So for example, for useEffect it means the callback will run once at the beginning of the lifecycle of the component and never again. In other words, Giving it an empty array acts like componentDidMount as in, it only runs once.

However, if you give it no argument like so:

means it runs first on mount and then on every re-render.

Lastly, giving it an array as second argument with any value inside, eg , [variable1] will only execute the code inside your useEffect hook:

  • ONCE on mount
  • whenever that particular variable (variable1) changes