angularfix
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • Angular
  • AngularJS
  • Typescript
  • HTML
  • CSS
  • Javascript
Showing posts with label oop. Show all posts
Showing posts with label oop. Show all posts

Sunday

How to infer class properties type without extending the class

 6:58 PM     oop, typescript, typescript-generics     No comments   

Issue

class XClass {
x = "x";
y = 11;
b = true;
}
let xObj = new XClass();
function getSchema<T extends XClass>(instance: T): Record<keyof T, T[keyof T]> {
const returnObj = {} as Record<keyof T, T[keyof T]>;
for (const key in instance) {
  returnObj[key] = instance[key]; // Direct assignment infers correct types
}
return returnObj;
}
let schema = getSchema(xObj);
type X = typeof schema;


/* type being inferred as 
type X = {
x: string | number | boolean;
y: string | number | boolean;
b: string | number | boolean;
}

// It should be instead :
type X = {
x: string;
y: number;
b: boolean;
}
*/

Typescript is inferring the types as a union. When i want to infer type of class properties each key is being inferred as all the possible types of the class properties.


Solution

You can use the following mapped type:

type ClassProps<T> = {
  [K in keyof T]: T[K]
}

Full code:

class XClass {
  x = "x";
  y = 11;
  b = true;
}

type ClassProps<T> = {
  [K in keyof T]: T[K]
}

function getSchema<T extends XClass>(instance: T): ClassProps<T> {
  const returnObj = {} as ClassProps<T>;
  for (const key in instance) {
    returnObj[key] = instance[key];
  }
  return returnObj;
}

const xObj = new XClass();
const schema = getSchema(xObj);
type X = typeof schema;
// type X = {
//   x: string;
//   y: number;
//   b: boolean;
// }

Playground link



Answered By - Lesiak
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Tuesday

NestJS typeorm generic inheritance of Repository not working, this.function is not a function

 12:01 PM     nestjs, oop, typeorm, typescript     No comments   

Issue

Iam trying to create a custom repository class that extends Repository so I can add custom log functions to be used from all repositories. here is the code.

user.service.ts:

@Injectable()
export class UserService {
    constructor(
        @InjectRepository(User)
        private readonly userRepository: BaseRepository<User>,
    ) {}

    async update(id: string, data: UpdateUserDto): Promise<UpdateResult> {
        return await this.userRepository.updateAndLog(id, data);
    }
}

BaseRepository.ts:

import { Repository, UpdateResult } from 'typeorm';


export class BaseRepository<T> extends Repository<T> {

  async updateAndLog(id: string, data: any): Promise<UpdateResult> {
    const entity = await this.findOne(id as any);
    const savedEntity = await this.update(id, data);
    // log the data here
    return savedEntity;
  }
}

so the output of the function is always:

[Nest] 13820  - 04/11/2023, 12:07:07 PM   ERROR [ExceptionsHandler] this.userRepository.updateAndLog is not a function

I read typeorm documentation about custom repositories: https://typeorm.io/custom-repository#how-to-create-custom-repository

StackOverflow:

  • How to do custom repository using TypeORM (MongoDB) in NestJS?
  • NestJS/TypeORM: Can custom repository extend from another custom repository which is inside another project?

github: https://github.com/typeorm/typeorm/issues/2097

Yet nothing is working, is there something wrong with the following code ?


Solution

The problem here comes from the @InjectRepository(User) : it injects an instance of Repository instead of the BaseRepository one.

I found this repository that provide a way to override the repository provided by the TypeORM module, but only for a specific entity.

However, we could adapt his approach to provide a generic repository instead :

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  providers: [buildCustomRepositoryProvider<User>(User), UserService],
})
export class UserModule {
}

With a helper file like this :

import { DataSource, Repository, UpdateResult } from 'typeorm';
import { Provider } from '@nestjs/common';
import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
import { EntityClassOrSchema } from '@nestjs/typeorm/dist/interfaces/entity-class-or-schema.type';

export interface BaseRepository<T> extends Repository<T> {
  this: Repository<T>;

  updateAndLog(id: string, data: any): Promise<UpdateResult>;
}

export function buildCustomRepositoryMethods<T>(): Pick<BaseRepository<T>, 'updateAndLog'> {
  return {
    async updateAndLog(id: string, data: any): Promise<UpdateResult> {
      const entity = await this.findOne({ where: { id: id as any } });
      const savedEntity = await this.update(id, data);
      // log the data here
      return savedEntity;
    },
  };
}

export function buildCustomRepositoryProvider<T>(entity: EntityClassOrSchema): Provider {
  return {
    provide: getRepositoryToken(entity),
    inject: [getDataSourceToken()],
    useFactory: (dataSource: DataSource) => {
      // Override the default repository with a custom one
      return dataSource.getRepository(entity).extend(buildCustomRepositoryMethods<T>());
    },
  };
}

Therefore, the @InjectRepository(User) will inject an instance of Repository<User> extended with the methods provided by the BaseRepository interface.

(Note : using the extend method here to create a custom repository as it's the recommended way since TypeORM 0.3, see here)



Answered By - Enalla
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Saturday

In typescript, how can I extend a class from it's instance?

 3:53 AM     object, oop, prototype, typescript     No comments   

Issue

Hello I am trying to basically inherit the Vehicle class within the Car class without using extends. I am wanting to do this because I am making a browser extension and I do not have access to the class, but I do have access to the instance. This works as expected, but typescript is throwing an error on the Car class line

Class 'Car' incorrectly implements interface 'ICar'.
  Type 'Car' is missing the following properties from type 'ICar': steer, accelerate, brake

If the code works as I expect it does, it should log out "Steering" and "Honking"

https://www.typescriptlang.org/playground/CarExample

interface IVehicle {
    steer(): void;
    accelerate(): void;
    brake(): void;
}

interface ICar extends IVehicle {
    honk(): void;
}

class Vehicle implements IVehicle {
    constructor(){
        console.log("Vehicle created");
    }
    steer(): void {
        console.log("Steering");
    }
    accelerate(): void {
        console.log("Accelerating");
    }
    brake(): void {
        console.log("Braking");
    }
}

class Car implements ICar {
    constructor(veh: IVehicle){
        Object.setPrototypeOf(this, Object.getPrototypeOf(veh));
        Object.assign(this, veh);
        // Even with the two lines above, it is saying that the object is missing the methods, "steer", "accelerate", and "brake"
    }
    honk(): void {
        console.log("Honking");
    }
}

const veh = new Vehicle();
const car = new Car(veh);

console.log(car.steer());
console.log(car.honk());

Solution

You need to create a Car interface which extends IVehicle

interface IVehicle {
    steer(): void;
    accelerate(): void;
    brake(): void;
}

interface ICar extends IVehicle {
    honk(): void;
}

class Vehicle implements IVehicle {
    constructor() {
        console.log("Vehicle created");
    }
    steer(): void {
        console.log("Steering");
    }
    accelerate(): void {
        console.log("Accelerating");
    }
    brake(): void {
        console.log("Braking");
    }
}

interface Car extends ICar { } // <----------- SEE THIS CHANGE

class Car {
    constructor(public veh: IVehicle) {
        Object.setPrototypeOf(this, Object.getPrototypeOf(veh));
        Object.assign(this, veh);
        // Even with the two lines above, it is saying that the object is missing the methods, "steer", "accelerate", and "brake"
    }
    honk(): void {
        console.log("Honking");
    }
}

const veh = new Vehicle();
const car = new Car(veh);

console.log(car.steer()); // ok
console.log(car.honk()); // ok

Playground

It is called declaration merging



Answered By - captain-yossarian from Ukraine
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Thursday

Is there a way to get type information from an inherited generic abstract class in typescript?

 9:40 AM     design-patterns, oop, typescript, typescript-generics, typescript-typings     No comments   

Issue

Given a scenario where I want to be able to 'tag' data coming into my system from various sources how might I go about adding this source information onto any type T within my system given some 'source' function that provides this mapping

The shape of the data I want to append this tagged information onto doesn't particularly matter - all I want users of my API to care about is providing a function that will use their type T to determine where the source is coming from and then a simple translation function of the new unioned type.

I've tried doing something like so:

enum TAG {
  EXTERNAL_SYSTEM_A,
  EXTERNAL_SYSTEM_B,
  EXTERNAL_SYSTEM_C,
  UNKNOWN
}

interface TAGSource {
  sourceTypes: TAG | TAG[];
}

// This can be literally any type at all
interface ExternalEntity {
  name: string;
}

interface CalendarEntity{
  id: number;
}

type SourceTagged<T> = T & TAGSource;

abstract class SourceTagMapper {
  tagEntity<T>(entity: T): SourceTagged<T> {
    return { sourceTypes: this.mapSourceTypes(entity), ...entity };
  }
  protected abstract mapSourceTypes<T>(entity: T):  TAG | TAG[];
}

// Example user implementation
class ExternalEntitySourceTagMapper extends SourceTagMapper{
  mapSourceTypes<ExternalEntity>(entity: ExternalEntity): TAG | TAG[] {
    // Error: Property 'name' does not exist on type 'ExternalEntity'
    console.log(entity.name);
    // do some work to map external entity to a tag
    return TAG.EXTERNAL_SYSTEM_A;
  }
}

// Example user implementation
class CalendarEntitySourceTagMapper extends SourceTagMapper {
  mapSourceTypes<CalendarEntity>(entity: CalendarEntity): TAG | TAG[] {
    // Error: Property 'id' does not exist on type 'CalendarEntity'
    console.log(entity.id);
    return [TAG.EXTERNAL_SYSTEM_B, TAG.EXTERNAL_SYSTEM_C];
  }
}

But the problem with this approach is I get no type information in the mapSourceTypes function due to the erasure of type information at runtime. I'm struggling to come up with a design that gives users the ability to just supply a function for mapping and then provides a function for 'providing' this mapping back to them with the added type information.

I tried inheriting from an abstract class with a generic function but lost type information in my base classes but due to type erasure the properties no longer exist in my derived class. Any thoughts or consideration for improvement would be greatly appreciated.


Solution

The generic should be on the class, not the methods ! That allows you to extends a generic class with a specified type.

abstract class SourceTagMapper<T> {
  tagEntity(entity: T): SourceTagged<T> {
    return { sourceTypes: this.mapSourceTypes(entity), ...entity };
  }
  protected abstract mapSourceTypes(entity: T):  TAG | TAG[];
}

// Example user implementation
class ExternalEntitySourceTagMapper extends SourceTagMapper<ExternalEntity>{
  mapSourceTypes(entity: ExternalEntity): TAG | TAG[] {
    // Error: Property 'name' does not exist on type 'ExternalEntity'
    console.log(entity.name);
    // do some work to map external entity to an lvc type
    return TAG.EXTERNAL_SYSTEM_A;
  }
}

// Example user implementation
class CalendarEntitySourceTagMapper extends SourceTagMapper<CalendarEntity> {
  mapSourceTypes(entity: CalendarEntity): TAG | TAG[] {
    // Error: Property 'id' does not exist on type 'CalendarEntity'
    console.log(entity.id);
    return [TAG.EXTERNAL_SYSTEM_B, TAG.EXTERNAL_SYSTEM_C];
  }
}

Playground



Answered By - Matthieu Riegler
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

TypeScript functional programming patterns for comfortable object construction?

 4:18 PM     functional-programming, javascript, oop, typescript     No comments   

Issue

I'm having a hard time finding examples (videos or blogs) of functional programming object construction patterns.

I recently encountered the below snipped builder pattern and I like the experience it provides for constructing an object with nesting. When it's a flatter object, I'd normally just use a simple object factory with an opts param to spread with defaults, but passing in a nested array of objects starts to feel messy.

Are there FP patterns that can help make composing an object with nesting like the below comfortable while allowing for calling some methods n times, such as addStringOption?

const data = new SlashCommandBuilder()
    .setName('echo')
    .setDescription('Replies with your input!')
    .addStringOption(option =>
        option.setName('input')
            .setDescription('The input to echo back')
            .setRequired(true)
    )
    .addStringOption(option =>
        option.setName('category')
            .setDescription('The gif category')
            .setRequired(true)
            .addChoices(
                { name: 'Funny', value: 'gif_funny' },
                { name: 'Meme', value: 'gif_meme' },
                { name: 'Movie', value: 'gif_movie' },
  ));

data ends up looking something like:

{
  name: "echo",
  description: "Replies with your input!",
  options: [
    {
      name: "input",
      description: "The input to echo back",
      type: 7, // string option id
      required: true,
      choices: null,
    },
    {
      name: "category",
      description: "The gif category",
      required: true,
      type: 7,
      choices: [
        { name: "Funny", value: "gif_funny" },
        { name: "Meme", value: "gif_meme" },
        { name: "Movie", value: "gif_movie" },
      ],
    },
  ],
};

Below is what I'm playing around with. I'm still working on learning how to type them in TS so I'm sharing the JS.

Allowing for method chaining in the below snippet is maybe contorting FP too much make it like OOP, but I haven't found an alternative that makes construction flow nicely.

An alternative could be standalone builders each returning a callback that returns the updated state then pipe these builders together, but with some builders being callable n times it's hard to make and provide the pipe ahead of time and without the dot notation providing intellisense it seems harder to know what the available functions are to build with.

const buildCommand = () => {
  // data separate from methods.
  let command = {
    permissions: ['admin'],
    foo: 'bar',
    options: [],
  };

  const builders = {
    setGeneralCommandInfo: ({ name, description }) => {
      command = { ...command, name, description };
      // trying to avoid `this`
      return builders;
    },

    setCommandPermissions: (...permissions) => {
      command = { ...command, permissions };
      return builders;
    },

    addStringOption: (callback) => {
      const stringOption = callback(buildStringOption());
      command = { ...command, options: [...command.options, stringOption] };
      return builders;
    },
    // can validate here
    build: () => command,
  };

  return builders;
};

const buildStringOption = () => {
  let stringOption = {
    choices: null,
    type: 7,
  };

  const builders = {
    setName: (name) => {
      stringOption = { ...stringOption, name };
      return builders;
    },

    setDescription: (description) => {
      stringOption = { ...stringOption, description };
      return builders;
    },

    addChoices: (choices) => {
      stringOption = { ...stringOption, choices };
      return builders;
    },

    build: () => stringOption,
  };

  return builders;
};

const command1 = buildCommand()
  .setGeneralCommandInfo({ name: 'n1', description: 'd1' })
  .setCommandPermissions('auditor', 'moderator')
  .addStringOption((option) =>
    option.setName('foo').setDescription('bar').build()
  )
  .addStringOption((option) =>
    option
      .setName('baz')
      .setDescription('bax')
      .addChoices([
        { name: 'Funny', value: 'gif_funny' },
        { name: 'Meme', value: 'gif_meme' },
      ])
      .build()
  )
  .build();

console.log(command1);

Solution

Why not simply create and use data constructors?

const SlashCommand = (name, description, options) =>
  ({ name, description, options });

const StringOption = (name, description, required, type = 7, choices = null) =>
  ({ name, description, required, type, choices });

const Choice = (name, value) => ({ name, value });

const data = SlashCommand('echo', 'Replies with your input!', [
  StringOption('input', 'The input to echo back', true),
  StringOption('category', 'The gif category', true, undefined, [
    Choice('Funny', 'gif_funny'),
    Choice('Meme', 'gif_meme'),
    Choice('Movie', 'gif_movie')
  ])
]);

console.log(data);

TypeScript Playground Example

You can't get more functional than this. Intellisense will also help you with the constructor arguments.



Answered By - Aadit M Shah
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Sunday

Assigining type to dynamically accessed object values

 3:55 PM     javascript, oop, types, typescript     No comments   

Issue

I have created a class which has 2 properties storing arrays of tuples with numbers. I also have created a method "getIndex" that accesses those properties dynamically and then checks whether there is a tuple containing identical numbers. The function looks like this:

  getIndex(posX: number, posY: number, pathArr: string) {
    for (let routeCoordinates of this[pathArr]) {
      if (routeCoordinates[0] === posX && routeCoordinates[1] === posY) {
        return this[pathArr].indexOf(routeCoordinates);
      }
    }
  }

The problem is that whenever I try to pass pathArr as a key I get the following error message:

"Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'PathfinderSecondStage'. No index signature with a parameter of type 'string' was found on type 'PathfinderSecondStage'."

I know about generics but solutions I found on the internet do not work as I am dealing with a class instance. Is there a solution that keeps typechecking?


Solution

The immediate solution is pretty simple. All you need to do is change pathArr: string parameter to pathArr: keyof PathfinderSecondStage which will cause TypeScript to create a union type of all the public fields/methods within the class and then extract the this[pathArr] statement and assign it into a variable with the assistance of type assertion to tell it the exact type that is going to be used:

 getIndex(posX: number, posY: number, pathArr: keyof PathfinderSecondStage) {
    const myArray = this[pathArr] as number[][];
    for (let routeCoordinates of myArray) {
      if (routeCoordinates[0] === posX && routeCoordinates[1] === posY) {
        return myArray.indexOf(routeCoordinates);
      }
    }
  }

You can additionally narrow down the allowed variables for the pathArr parameter by specifically defining the names of the fields that contain the arrays which can be traversed within the function as below: getIndex(posX: number, posY: number, pathArr: 'fieldName1'|'fieldName2') {

This will narrow down the number of types TypeScript needs to create a union type with, and if they are all arrays of numbers (number[][]), you will not need to do the type assertion as displayed in the first example.



Answered By - Ovidijus Parsiunas
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Friday

Service heritage in Angular 2+

 11:46 PM     angular, angular-services, oop, typescript     No comments   

Issue

I have one component that inherits from a parent class, which itself gets injected a service. That service is also used in the child class (the component). Am I obliged to import and inject the service twice, both in the parent and the child class?

It seems like code duplication to me (and a little chicken-and-eggish as the child must import the service to pass it as a parameter to the parent... which already imports it!).

app.component.ts (child class)

import { Component, OnInit } from '@angular/core';
import { HelperClass } from 'src/app/helper-class';
/**** Duplicate import with the parent class HelperClass ****/
import { MyService } from 'src/app/my-service.service';

@Component({
  selector: 'app-my-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})
export class MyComponent extends HelperClass implements OnInit {

  /**** Duplicate injection with HelperClass ****/
  constructor(private service: MyService) {
    super(service);
  }

  ngOnInit(): void {
    this.myService.log('my service called in MyComponent');
    this.helper_class_method();
  }

}

helper-class.ts (parent class)

import { MyService } from 'src/app/my-service.service';

export class HelperClass {
  constructor(public myService: MyService) { }

  helper_class_method() {
    console.log('helper_class method');
  }
}

my-service.service.ts

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyService {
  log(text: string) { console.log(text); }
}

Sample code is available at https://github.com/manu2504/service-heritage-angular/blob/main/src/app/app.component.ts


Solution

I made the helper/parent class a service, that I inject in the component, and this solves the problem.

The component can access the public properties of the helper service, including the services imported by the helper service, and there is no more the need to import myService in the component.

New code:

helper-class.ts

import { Injectable } from '@angular/core';
import { MyService } from 'src/app/my-service.service';

@Injectable({
  providedIn: 'root'
})
export class HelperClass {
  constructor(public myService: MyService) { } 

  helper_class_method() {
    console.log('helper_class method');
  }
}

app.component.ts

import { Component, OnInit } from '@angular/core';
import { HelperClass } from 'src/app/helper-class';

@Component({
  selector: 'app-my-component',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.sass']
})
export class MyComponent implements OnInit {

  // Duplicate injection with HelperClass
  constructor(
    private helper: HelperClass
  ) { }

  ngOnInit(): void {
    // No more the need to declare myService locally
    this.helper.myService.log('my service called in MyComponent');
    this.helper.helper_class_method();
  }
}


Answered By - manuchaud100
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Wednesday

Map is coming up as undefined - OpenLayers

 3:12 PM     angular, javascript, maps, oop, openlayers-6     No comments   

Issue

I am experiencing a strange issue. I am receiving an error message that reads "ERROR TypeError: Cannot read properties of null (reading 'map_') on line 29". Even though I am able to loop the layers on the map to get the list of features on hover (line 23). Please see my code below and let me know if you have any advice on what I can do to fix this.

The way this is set up is, that my component is using a service that holds the information about the map and overlay. All I want to do is set the position of overlay on hover.

Component

import { Component, OnInit } from '@angular/core';
    import { Map } from 'ol';
    import { GeneralMapService } from 'src/app/services/general-map.service';
    
    @Component({
      selector: 'app-application-map',
      templateUrl: './application-map.component.html',
      styleUrls: ['./application-map.component.css']
    })
    
    export class WhereisMapComponent implements OnInit {

  map_: Map;
  overlay: any;

  constructor(private generalMap: GeneralMapService) {
    this.map_ = this.generalMap.map
    
    this.map_.on("pointermove", (e) => {
      
      const positionOfMouse = e.coordinate
      
      this.map_.forEachFeatureAtPixel(e.pixel, function (feature) {
        
        if (feature) {
          const { as_tr_name, ass_track, id, descriptio, media } = feature.getProperties();

          // I receive an error message here.
          console.log(this.map_.getView())
          this.map_.getView().mapOverlay.setPosition(positionOfMouse);
        }

      })

    })

    this.overlay = document.getElementById('informationOverlay')
    this.generalMap.mapOverlay.set("id", "informationOverlay")
    this.generalMap.mapOverlay.setElement(this.overlay)

  }

  ngOnInit(): void {
  }

  ngAfterViewInit() {
    this.map_.setTarget("map")  

  }

}

General Service

import { Injectable } from '@angular/core';
import { Map, Overlay, Tile, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
import { Zoom, ZoomSlider, FullScreen } from 'ol/control';
import XYZ from 'ol/source/XYZ';
import BingMaps from 'ol/source/BingMaps';
import LayerGroup from 'ol/layer/Group';

import { mapDefaultCenter, mapeDefaultZoom } from '../shared/maptilerkey';
import { CreateLayerService } from './create-layer.service';
import { Fill, Stroke, Style } from 'ol/style';
import CircleStyle from 'ol/style/Circle';
import { OverlayService } from './overlay.service';

@Injectable({
  providedIn: 'root'
})
export class GeneralMapService {

  map: Map;
  zoomSlider: ZoomSlider = new ZoomSlider({
    className: "zoom-slider-dashboard"
  })
  mapLayers: LayerGroup = new LayerGroup({
    layers: []
  })
  mapOverlay: Overlay;

  constructor(private createLayers: CreateLayerService, overlayService: OverlayService) {

    const topographicLayer = new TileLayer({
      source: new XYZ({
        url: "https://api.maptiler.com/maps/topographique/{z}/{x}/{y}@2x.png?key=WYPadsIvfisd0PUHFJ6K"
      }),
      visible: false
    })
    topographicLayer.set('name', 'topographic');

    const openStreetMap = new TileLayer({
      source: new OSM(),
      visible: true
    })
    openStreetMap.set('name', 'openstreetmap');

    const bingMaps = new TileLayer({
      preload: Infinity,

      source: new BingMaps({
        key: 'AngczjEvgHNjwD8lTQe3DJ6CoFxavJfGTFCxxaGbS3bIgUW5_qn4k_m510RR53fe',
        imagerySet: "Aerial",
        hidpi: true,
        maxZoom: 19
      }),
      visible: false
    })
    bingMaps.set('name', 'bingmap');

    this.map = new Map({
      view: new View({
        center: mapDefaultCenter,
        zoom: mapeDefaultZoom,
        minZoom: 5,
        projection: "EPSG:3857",
        extent: [15766342.542104144, -5590291.031415702, 16739198.402589425, -4713511.626202316]
      }),
      controls: []
    })

    const mapLayerGroup = new LayerGroup({
      layers: [topographicLayer, openStreetMap, bingMaps]
    })

    this.map.setLayerGroup(mapLayerGroup)
    this.map.addControl(this.zoomSlider)

    // vector layer
    const walkPointStyle = new Style({
      image: new CircleStyle({
        radius: 6,
        fill: new Fill({
          color: '#44c4a1',
        }),
        stroke: new Stroke({
          color: '#fff',
          width: 2,
        }),
      }),
    })

    const walkPoints = this.createLayers.createVectorLayer("/assets/data/walking-data.geojson", walkPointStyle)
    const builtMapLayers = [
      walkPoints
    ]

    this.map.getLayers().extend(builtMapLayers)

    // Overlay registration
    this.mapOverlay = overlayService.overlay
    this.map.addOverlay(this.mapOverlay)
    console.log("this.map", this.map.getOverlays())

  }

  ngAfterContentInit() {

  }

  returnMap() {
    return this.map;
  }

  setMap(updatedMap: Map) {
    this.map = updatedMap;
  }
}

Any sort of help would be appreciated!


Solution

It looks like you need to store context somewhere and then try to use that context forEachFeatureAtPixel method.

Let me show an example:

let that = this;

this.map_.forEachFeatureAtPixel(e.pixel, function (feature) {
        
    if (feature) {
      // ... other code is omitted for the brevity
     
      console.log(that.map_.getView())
      that.map_.getView().mapOverlay.setPosition(positionOfMouse);
    }


Answered By - StepUp
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Friday

is there a way to put the method functions of a class, in separate files (javascript)?

 5:11 AM     class, coding-style, html, javascript, oop     No comments   

Issue

if there is a way to split and make the code of every method in a separate file?

so I can have clean code and be simple and easier to maintain.

for now, I have a structure like this (minimal reproducible example):

// there is also a parentClass
// and I want to make sure that the method be inside parent
// so I can modify all the childs
// with the same method

class Parent {
  // myMethod.js
  myMethod() {
    // my long code
  }

  //secondMethod.js
  secondMethod() {
    // my long code
  }

  // thirdMethod.js
  thirdMethod() {
    // my long code
  }
}
class Child extends Parent {
  constructor() {
    this.someData = "someData";
  }
}

// this need to work after putting the file externally for example
new Child.myMethod();

but I want that the methods be in separate files

something like this: enter image description here

the problem is how can a method know that is been part of a specific Class and not another Class for example.


for example If we want to separate the Child from parentClass, this is easy:

  • thanks to import, export, extends

import ParentClass from './ParentClass.js';

// here since we have "extends" the child class know that is been part of Parent.
export default class Child extends ParentClass {
  // my child things and it will work
}

// but methods don't have extends or similar thing? 
// and if yes how we can export them? 
// export as a function? 
// (but they aren't function, they are methods?)


so what do I want?

  1. method -> file
  2. file -> method can be exported
  3. method -> parentClass can import it
  4. import -> method be part of parentClass
  5. method ParentClass -> get extended to all childs
  6. method extended -> read (and change) correctly the values of this. (like it was before inside with code splitting)

Solution

Some languages support partial classes, which is similar to what you are requesting. They don't get used a great deal as they make it hard to understand a class when it's internals are scattered around your project.

A more OOP way to solve your problem is to look at the parts you label // my long code.

You can usually break up that code and place it in other classes that you delegate the request to. For example, if your long code does many things:

myMethod(input) {
    // Map the input into a different shape
    // Part of the long code
    // Perform some form of calculation on some values
    // Another part of the long code
    // Create a response object and return it
    // This part probably isn't too long
    return response;
}

You might be able to split these up by creating a class that does mapping and a class that does the calculation. This means the mapping and calculation are easily used from other places and reduces the length of code in your method:

myMethod(input) {
    const mapped = this.specificMapper.map(input);
    const response = this.specificCalculator.calculate(mapped);
    return response;
}


Answered By - Fenton
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Wednesday

Typescript Overwrite Constructor Arguments in Mixin

 1:53 PM     ecmascript-6, javascript, oop, typescript     No comments   

Issue

In my current typescript project I'm trying to create a mixin so that I can create multiple child classes that inherit from different base classes.

It all works well, but I can't seem to figure out how to tell typescript that the new derived class has different arguments than the base class. Here's an example that illustrates what I'm trying to do here

interface ConstructorFoo {
  bar: string,
}

class Foo {
  public bar: string
  constructor({ bar }: ConstructorFoo) {
    this.bar = bar
  }
}

interface ConstructorBaz extends ConstructorFoo {
  qux: string
}

type FooType = new (...args: any[]) => Foo
const quxMixin = <T extends FooType>(base: T) => {
  return class Baz extends base {
    public qux: string
    constructor (...args: any[]) {
      super(...args)
      const { qux } = args[0] as ConstructorBaz
      this.qux = qux
    }
  }
}

const FooBaz = quxMixin(Foo)


const q = new FooBaz({
  bar: '1',
  qux: '2'  // Argument of type '{ bar: string; qux: string; }' is not assignable to parameter of type 'ConstructorFoo'.
            // Object literal may only specify known properties, and 'qux' does not exist in type 'ConstructorFoo'.
})

But I get the following error as I don't know how to specify class Baz has different argument types:

Argument of type '{ bar: string; qux: string; }' is not assignable to parameter of type 'ConstructorFoo'.
Object literal may only specify known properties, and 'qux' does not exist in type 'ConstructorFoo'.

Thanks for your help and here's a playground link detailing exactly what I want to do


Solution

Try this:

/** A constructor that constructs a T using the arguments A */
type Constructor<T = any, A extends any[] = any[]> = new (...args: A) => T
/** Exclude the first element of an array */
type Tail<T extends any[]> = T extends [any, ...infer U] ? U : never

interface Qux {
  qux: string
}

/** Add the Qux type to the first item in an array */
// If the T is empty, T[0] will be never and T[0] & Qux will also be never, so
// this needs to check if the array is empty
type AddQux<T extends any[]> = T extends [] ? [Qux] : [T[0] & Qux, ...Tail<T>]

// quxMixin accepts a constructor base and returns another constructor
const quxMixin = <T extends Constructor>(base: T): Constructor<
  // that constructs the original class with the qux property
  InstanceType<T> & Qux,
  // using the same arguments as the original constructor except that the first
  // parameter includes the qux property
  AddQux<ConstructorParameters<T>>
> => {
  return class Baz extends base {
    public qux: string
    constructor (...args: any[]) {
      super(...args)
      const { qux } = args[0] as Qux
      this.qux = qux
    }
  }
}

const FooBaz = quxMixin(Foo)

const q = new FooBaz({ bar: '1', qux: '2' })
q.qux // string

This uses the utility types InstanceType and ConstructorParameters:

/** Obtain the return type of a constructor function type */
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any

/** Obtain the parameters of a constructor function type in a tuple */
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never

Playground link



Answered By - cherryblossom
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Friday

How can I write below code in better way to keep looping endlessly?

 9:59 AM     angularjs, javascript, oop, php     No comments   

Issue

This is my first time on Stackoverflow so please bear with me if my question is not clear !. I am trying to fetch all rows from tblproperty and loop through the array to convert it into an associative array. Once the property is fetched i am checking if the property is of the page or object. If the property if of the page we add the same in the propertiesArray. If the property is of object I am checking if the object is of the page or child of another parent object. The code below works for 3 levels (meaning Parent > Child > Child > Child). However I need to improve it to loop continuously if the object is of another parent object. Need advice how can I improve it. Further below code is in PHP on Server Side. I am looking to take it to Client Side. Any way to do it in Angular JS. Thanks in advance to all who chose to help !

$DBObj->querySelect("*","tblproperty","pgnid = $pageNID and propisactive = 1");

if($DBObj->fetchNumOfRows() >= 1){
    $queryRecords = $DBObj->fetchAllRecordsArray();
    $rows = $DBObj->fetchNumOfRows();
    
    for($i = 0; $i < $rows; $i++){
        //Properties of Objects are Loaded to Object Properties Array
        
        switch ($queryRecords[$i]['propof']){
            case "page":{
                if(array_key_exists($queryRecords[$i]['propofid'],$propertiesArray) != 1)
                    $propertiesArray[$queryRecords[$i]['propofid']] = [];
                array_push($propertiesArray[$queryRecords[$i]['propofid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));                                        
                break;
            }
                
            case "object":{
                $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecords[$i]['propofnid']);
                $queryRecord = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";
                
                if($queryRecord != "")
                    switch($queryRecord['objof']){
                        case "object":{
                            $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecord['objofnid']);
                            $queryRecord1 = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";

                            if($queryRecord1 != "")
                                switch($queryRecord1['objof']){
                                    case "object":{
                                        $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecord1['objofnid']);
                                        $queryRecord2 = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";
                                        
                                        if($queryRecord2 != "")
                                            switch($queryRecord2['objof']){
                                                case "object":{
                                                    if(array_key_exists($queryRecord2['objofid'].$queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid'],$propertiesArray) != 1)
                                                        $propertiesArray[$queryRecord2['objofid'].$queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid']] = [];
                                                    array_push($propertiesArray[$queryRecord2['objofid'].$queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));
                                                    break;
                                                }
                                                    
                                                case "page":{
                                                    if(array_key_exists($queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid'],$propertiesArray) != 1)
                                                        $propertiesArray[$queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid']] = [];
                                                    array_push($propertiesArray[$queryRecord1['objofid'].$queryRecord['objofid'].$queryRecords[$i]['propofid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto'])); 
                                                    break;
                                                }
                                            }
                                        break;
                                    }

                                    case "page":{
                                        if(array_key_exists($queryRecord['objofid'].$queryRecords[$i]['propofid'],$propertiesArray) != 1)
                                            $propertiesArray[$queryRecord['objofid'].$queryRecords[$i]['propofid']] = [];
                                        array_push($propertiesArray[$queryRecord['objofid'].$queryRecords[$i]['propofid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));
                                        break;
                                    }
                                }
                            break;
                        }

                        case "page":{
                            if(array_key_exists($queryRecords[$i]['propofid'],$propertiesArray) != 1)
                                $propertiesArray[$queryRecords[$i]['propofid']] = [];
                            array_push($propertiesArray[$queryRecords[$i]['propofid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));                            
                            break;
                        }
                    }
                break;
            }
                
            case "element":{                    
                $DBObj->querySelect("*","tblelement","pgnid = $pageNID and elisactive = 1 and elnid = ".$queryRecords[$i]['propofnid']);
                $queryRecord = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";  
                
                if($queryRecord != ""){
                    $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecord['elofnid']);
                    $queryRecord1 = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";
                
                    if($queryRecord1 != "")
                        switch($queryRecord1['objof']){
                            case "object":{
                                $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecord1['objofnid']);
                                $queryRecord2 = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";
                                
                                if($queryRecord2 != ""){
                                    switch($queryRecord2['objof']){
                                        case "object":{
                                            $DBObj->querySelect("*","tblobject","pgnid = $pageNID and objisactive = 1 and objnid = ".$queryRecord2['objofnid']);
                                            $queryRecord3 = ($DBObj->fetchNumOfRows() == 1)?$DBObj->fetchRecordArray():"";
                                            
                                            if($queryRecord3 != ""){
                                                switch($queryRecord3['objof']){
                                                    case "object":{
                                                        
                                                        break;
                                                    }
                                                        
                                                    case "page":{
                                                        if(array_key_exists($queryRecord3['objid'].$queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid'],$propertiesArray) != 1)
                                                            $propertiesArray[$queryRecord3['objid'].$queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid']] = [];
                                                        array_push($propertiesArray[$queryRecord3['objid'].$queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));
                                                        break;
                                                    }
                                                }
                                            }
                                            break;
                                        }
                                            
                                        case "page":{
                                            if(array_key_exists($queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid'],$propertiesArray) != 1)
                                                $propertiesArray[$queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid']] = [];
                                            array_push($propertiesArray[$queryRecord2['objid'].$queryRecord1['objid'].$queryRecord['elid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));
                                            break;
                                        }
                                    }                                    
                                }                                                                
                                break;
                            }

                            case "page":{
                                if(array_key_exists($queryRecord1['objid'].$queryRecord['elid'],$propertiesArray) != 1)
                                    $propertiesArray[$queryRecord1['objid'].$queryRecord['elid']] = [];
                                array_push($propertiesArray[$queryRecord1['objid'].$queryRecord['elid']],array($queryRecords[$i]['propid'] => $queryRecords[$i]['propvalue'],'proplinkedto' => $queryRecords[$i]['proplinkedto']));                            
                                break;
                            }
                        }
                }
                break;
            }
        }
    }
} 

Solution

To iterate your object recursively you need ... recursion

Create separate function with conditions inside.

  • If current item belongs to page - push to array and return
  • If current item belongs to object - take child element and repeat this check again.

This is pseudo code, adjust how you need it:

if($DBObj->fetchNumOfRows() >= 1){
    $queryRecords = $DBObj->fetchAllRecordsArray();
    $rows = $DBObj->fetchNumOfRows();
    
    for($i = 0; $i < $rows; $i++){
        recursiveAction($queryRecords[$i]);
    }
}

function recursiveAction(&$item, $propertiesArray) {
    switch ($item['propof']) {
        case 'page':
            // No need for that "if" check
            $propertiesArray[$item['propofid']][] = [$item['propid'] => $item['propvalue'],'proplinkedto' => $item['proplinkedto']];

            break;
        case 'object':
            $DBObj->querySelect(...);
            $queryRecord = $DBObj->fetchNumOfRows() == 1 ? $DBObj->fetchRecordArray() : "";

            if (!empty($queryRecord)) {
                // Here we convert common part of "object" into recursion
                recursiveAction($queryRecord);
            }

            break;
      case 'element':
            ...
    }
}


Answered By - Justinas
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Wednesday

How to call a function with data from foreach method in HTML string?

 10:33 AM     html, javascript, loops, oop, typescript     No comments   

Issue

I am generating some html card and buttons from an array. I want to call a function with the data from the foreach. But I can't seem to figure it out.

I am getting the problem in the renderProducts() method.

/// <reference path="coin.ts" />
/// <reference path="product.ts" />
/// <reference path="productFactory.ts" />

enum VendingMachineSize {
  small = 6,
  medium = 9,
  large = 1,
}

class Cell {
  constructor(public product: CocoCola) {}
  stock: 3;
  sold: false;
}

class VendingMachine {
  private totalMoney = 0;
  private totalMoneyText = <HTMLSpanElement>document.getElementById("total-money");
  private containerElement = <HTMLDivElement>document.querySelector(".machine");
  allCoins: number[] = [0];
  cells = [];
  selectedCells = [new Cell(new CocoCola())];

  set size(givenSize: VendingMachineSize) {
    this.cells = [];

    for (let index = 0; index < givenSize; index++) {
      let product = ProductFactory.GetProduct();
      this.cells.push(new Cell(product));
    }
    this.renderProducts();
  }

  constructor() {
    console.log("I am vending machine!");
  }

  select(cell: Cell) {
    cell.sold = false;
    this.selectedCells.push(cell);
    console.log(this.selectedCells);
  }

  acceptCoin(coin: Quarter): void {
    this.totalMoney += coin.Value;
    this.totalMoneyText.textContent = this.totalMoney.toString();
  }

  renderProducts() {
    this.cells.forEach((product) => {
      let html = `<div class="card " style="width: 18rem">
        <img src=${product.product.category.getImageUrl()} class="" alt="..." />
        <div class="card-body">
          <h5 class="card-title">${product.product.name}</h5>
          <p class="card-text">
           ${product.product.description}
          </p>
          <button type="button" class="btn btn-outline-dark w-100 select-btn"  onclick="machine.select(${product})">💰 ${
        product.product.price
      }</button>
        </div>
      </div>`;
      this.containerElement.insertAdjacentHTML("beforeend", html);
    });
  }
}

<button type="button" class="btn btn-outline-dark w-100 select-btn" onclick="machine.select(${product})">💰 ${product.product.price}</button> I want this button to have an onclick listener with argument of product

When I do it like this it give me this error: Uncaught SyntaxError: Unexpected identifier (at (index):33:63)

This is where I created the instance of the class

/// <reference path="vendingMachine.ts" />

const machine = new VendingMachine();
machine.size = VendingMachineSize.medium;


Solution

You can not do it like that because you use string interpolation.

When you type

`some text ${product}`

and product is Object in your scope, javascript will call toString method on object and returns [Object object] <- here is the error that you recieved: **Uncaught SyntaxError: Unexpected identifier**

When you're trying to interpolate onclick handler, you should produce valid JS code, for example:

<div onclick="machine.select(${number})"></div>,
<div onclick="machine.select('${string}')"></div>,
<div onclick="machine.select(JSON.parse('${JSON.encode(product)}'))"></div>

I recommend set listener after generating html; For example:

<button type="button" data-product="${product.product.name}" class="btn btn-outline-dark w-100 select-btn">💰 ${product.product.price}</button>
...
this.containerElement.insertAdjacentHTML("beforeend", html);
this.containerElement.querySelectorAll('button').forEach(item => {
  item.addEventListener('click', () => {
    this.select(item.dataset.product)
  })
})


Answered By - Фарид Ахмедов
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Typescript: How to extend two classes?

 5:52 AM     extends, javascript, oop, typescript     No comments   

Issue

I want to save my time and reuse common code across classes that extend PIXI classes (a 2d webGl renderer library).

Object Interfaces:

module Game.Core {
    export interface IObject {}

    export interface IManagedObject extends IObject{
        getKeyInManager(key: string): string;
        setKeyInManager(key: string): IObject;
    }
}

My issue is that the code inside getKeyInManager and setKeyInManager will not change and I want to reuse it, not to duplicate it, here is the implementation:

export class ObjectThatShouldAlsoBeExtended{
    private _keyInManager: string;

    public getKeyInManager(key: string): string{
        return this._keyInManager;
    }

    public setKeyInManager(key: string): DisplayObject{
        this._keyInManager = key;
        return this;
    }
}

What I want to do is to automatically add, through a Manager.add(), the key used in the manager to reference the object inside the object itself in its property _keyInManager.

So, let's take an example with a Texture. Here goes the TextureManager

module Game.Managers {
    export class TextureManager extends Game.Managers.Manager {

        public createFromLocalImage(name: string, relativePath: string): Game.Core.Texture{
            return this.add(name, Game.Core.Texture.fromImage("/" + relativePath)).get(name);
        }
    }
}

When I do this.add(), I want the Game.Managers.Manager add() method to call a method which would exist on the object returned by Game.Core.Texture.fromImage("/" + relativePath). This object, in this case would be a Texture:

module Game.Core {
    // I must extend PIXI.Texture, but I need to inject the methods in IManagedObject.
    export class Texture extends PIXI.Texture {

    }
}

I know that IManagedObject is an interface and cannot contain implementation, but I don't know what to write to inject the class ObjectThatShouldAlsoBeExtended inside my Texture class. Knowing that the same process would be required for Sprite, TilingSprite, Layer and more.

I need experienced TypeScript feedback/advice here, it must be possible to do it, but not by multiple extends since only one is possible at the time, I didn't find any other solution.


Solution

There is a little known feature in TypeScript that allows you to use Mixins to create re-usable small objects. You can compose these into larger objects using multiple inheritance (multiple inheritance is not allowed for classes, but it is allowed for mixins - which are like interfaces with an associated implenentation).

More information on TypeScript Mixins

I think you could use this technique to share common components between many classes in your game and to re-use many of these components from a single class in your game:

Here is a quick Mixins demo... first, the flavours that you want to mix:

class CanEat {
    public eat() {
        alert('Munch Munch.');
    }
}

class CanSleep {
    sleep() {
        alert('Zzzzzzz.');
    }
}

Then the magic method for Mixin creation (you only need this once somewhere in your program...)

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
             if (name !== 'constructor') {
                derivedCtor.prototype[name] = baseCtor.prototype[name];
            }
        });
    }); 
}

And then you can create classes with multiple inheritance from mixin flavours:

class Being implements CanEat, CanSleep {
        eat: () => void;
        sleep: () => void;
}
applyMixins (Being, [CanEat, CanSleep]);

Note that there is no actual implementation in this class - just enough to make it pass the requirements of the "interfaces". But when we use this class - it all works.

var being = new Being();

// Zzzzzzz...
being.sleep();


Answered By - Fenton
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Thursday

How to auto-populate an abstract property?

 4:26 PM     class, oop, typescript     No comments   

Issue

I have an existing abstract class, say Vehicle and I want to create an intermediate class to reduce repetition of abstract properties in my instantiatable classes.

The problem:

abstract class Vehicle {
  abstract wheelCount: number
  abstract tireCount: number
}

class Car extends Vehicle {
  wheelCount = 4
  tireCount = 4 // Tire count is the same as wheel count
}

class Truck extends Vehicle {
  wheelCount = 4
  tireCount = 4 // Tire count is the same here too
}

class Bike extends Vehicle {
  wheelCount = 2
  tireCount = 2 // Tire count is the same - I really need to abstract this
}

An invalid solution:

abstract class Vehicle {
  abstract wheelCount: number
  abstract tireCount: number
}

// I want an intermediate class like this
abstract class StandardVehicle extends Vehicle {
  tireCount = wheelCount
}

class Car extends StandardVehicle {
  wheelCount = 4
}

class Truck extends StandardVehicle {
  wheelCount = 4
}

class Bike extends StandardVehicle {
  wheelCount = 2
}

What are the valid solutions to this please?

Please note, there are cases where wheelCount and tireCount will differ so I can't combine these properties in Vehicle.


Solution

It is possible to implement properties with getter and setter and then just assign their values in constructor.

So code would like this:

abstract class Vehicle {
  abstract wheelCount: number
  abstract tireCount: number
}

and class with properties and corresponding getters and setters:

abstract class StandardVehicle extends Vehicle {
    private _wheelCount!: number;
    get wheelCount(): number {
        return this._wheelCount;
    }
    set wheelCount(value: number) {
        this._wheelCount = value;
    }


    private _tireCount!: number;
    get tireCount(): number {
        return this._tireCount;
    }
    set tireCount(value: number) {
        this._tireCount = value;
    }

    constructor(wheelCount: number) {
        super()
        this._wheelCount = this._tireCount = wheelCount
    }
}

and it is possible to assign some common value in concrete class:

class Teasl extends StandardVehicle {
    constructor(value: number) {
        super(value)
    }
}

and you can call your class like this:

const anExampleVariable = new Teasl(88)

As an alternative, the initialization function can be created to populate with values.

So the code would look like this. Abstractions:

abstract class Vehicle {
  abstract wheelCount: number
  abstract tireCount: number
}

abstract class StandardVehicle extends Vehicle {
  constructor(value:number) {
      super()
      this.init(value)
  }

    private init(value:number) {
        this.wheelCount = this.tireCount = value
    }
}

and concrete implementations:

class Foo extends StandardVehicle {
    wheelCount!: number
    tireCount!: number

    constructor(value: number) {
        super(value)
    }
}

and usage:

const anExampleVariable = new Foo(88)
console.log(anExampleVariable)


Answered By - StepUp
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Wednesday

Typescript error: An outer value of 'this' is shadowed by this container

 10:06 AM     class, oop, typescript     No comments   

Issue

I had an error in a Typescript class method declaration, but I don't understand how the error message relates back to the bug.

The message seems to be saying that 'this' is of type any, but we are in a class definition, and so I thought 'this' was really clear.

Can someone please explain how the error message relates back to the bug?

Original method:

calcSize = function() {
    return this.width * this.length; // Error on this line
};

// Error text: 'this' implicitly has type 'any' because it does not 
//have a type annotation.ts(2683)
//app.ts(39, 16): An outer value of 'this' is shadowed by this container.

fix:

calcSize() {
    return this.width * this.length;
};

Full context (fixed):

class BaseObject {
    constructor(
        public width: number = 0,
        public length: number = 0
        ) {}

};

class Rectangle extends BaseObject {

    constructor(public width: number = 0, public length: number = 0) {
        super(width, length);
    }

    calcSize() {
        return this.width * this.length;
    };
}

Solution

In TypeScript (and ES6) exists two kinds of functions: The classic function declaration and the arrow function. Where the classic function declaration has the default floating binding logic for the this keyword - the arrow function will constantly use the value for this of the context containing the arrow function. In the example this will be the instance of the surrounding class.

class Rectangle extends BaseObject {
// ..
  calcSize = function() {
    // the keyword function will cause this to be floating
    // since the function is explicitly assigned to calcSize
    // (older) TypeScript may not infer the type of this.
    // the value of this can be re-bind by changing the context
    // using bind or call
    // -> Value of this defaults to the class instance
    return this.width * this.length; // (potential) type Error on this line
  };
  calcSizeAsMember () {
    // is also a classic function which will use floating binding
    // therefore this will be the type of the containing class
    // the value of this can be re-bind by changing the context
    // using bind or call
    // -> Value of this defaults to the class instance
    return this.width * this.length; 
  };
  calcSizeAsArrowFunction = () => {
    // is an arrow function which has a constantly bind this keyword, 
    // it is not possible to change the binding afterwords (not re-binding)
    // type of this is constantly the type of the containing class
    // changing the context, use bind or call will have no effect
    // -> this will always remain to the instance of the class
    return this.width * this.length; 
  };
};


Answered By - Matthias Fischer
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Monday

What is the difference between interface and abstract class in Typescript?

 2:40 AM     oop, typescript     No comments   

Issue

I wrote a couple of lines of code to experiment and differentiate between these two: interface and abstract class.

I found out that they have the same restriction.

interface IPerson {
  name: string;
  talk(): void;
}

interface IVIP {
  code: number;
}

abstract class Person {
  abstract name: string;
  abstract talk(): void;
}

class ManagerType1 extends Person {
  // The error I get is that I need to implement the talk() method
  // and name property from its base class.
}

class ManagerType2 implements IPerson {
  // The error I get is that I need to implement the talk() method 
  // and the name property from the interface.
}


class ManagerType3 implements IPerson, IVIP {
  // Now the error I get is that I need to implement all the 
  // properties and methods of the implemented interfaces to the derived class
}

As what I found is, there are no clear differences between these two since they both implement the same restriction. The only thing I notice is inheritance and implementation.

  1. A class can only extend to a single base class
  2. A class can implement multiple interfaces.

Did I catch it right? If so when do I need to use one?

UPDATE

I do not know if this is the right answer but you can really use BOTH depending on your situation. OOP is really cool.

class ManagerType3 extends Person implements IPerson, IVIP {
  // Now the restriction is that you need to implement all the abstract
  // properties and methods in the base class and all 
  // the properties and methods from the interfaces
}

Solution

Interfaces

An interface is a contract that defines the properties and what the object that implements it can do. For example, you could define what can do a Plumber and an Electrician:

interface Electrician {
  layWires(): void
}

interface Plumber {
  layPipes(): void
}

Then, you can consume the services of your interfaces:

function restoreHouse(e: Electrician, p: Plumber) {
  e.layWires()
  p.layPipes()
}

Notice that the way you have to implement an interface is free. You can do that by instantiating a class, or with a simple object:

let iAmAnElectrician = {
  layWires: () => { console.log("Work with wires…") }
}

An interface doesn't exist at all at runtime, so it is not possible to make an introspection. It is the classic JavaScript way to deal with object programming, but with a good control at compile time of the defined contracts.

Abstract classes

A class is both a contract and the implementation of a factory. An abstract class is also an implementation but incomplete. Especially, an abstract class exists at runtime, even if it has only abstract methods (then instanceof can be used).

When you define an abstract class, you often try to control how a process has to be implemented. For example, you could write something like this:

abstract class HouseRestorer {
  protected abstract layWires(): void
  protected abstract layPipes(): void
  restoreHouse() {
    this.layWires()
    this.layPipes()
  }
}

This abstract class HouseRestorer defines how the methods layWires and layPipes will be used, but it is up to a child class to implement the specialized treatments before it can be used.

Abstract classes are a traditional OOP approach, which is not traditional in JavaScript.

Both approaches allow the same things to be done. But they are two different ways of solving a problem.



Answered By - Paleo
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Wednesday

Typescript: ReferenceError: Cannot access 'Store' before initialization

 4:46 PM     inheritance, oop, typescript     No comments   

Issue

I have a class Store which incapsulates State (mobx used).

export class Store<State> {
    @observable
    public state: State;

    constructor(protected rootStore: RootStore, state: State) {
        this.state = state || ({} as State);
    }

    @action
    setState(state: State) {
        this.state = {
            ...this.state,
            ...state
        };
    }
}

And I'm trying to implement a class UserState:

interface UserState {
    authorised?: boolean;
    loading?: boolean;
    name?: string;
    balance?: number;
}

export class UserStore extends Store<UserState> {
    constructor(rootStore: RootStore) {
        super(rootStore, {
            authorised: false,
            loading: true,
            name: ''
        })
    }
}

Everything seems right for me, but I have an error:

ReferenceError: Cannot access 'Store' before initialization

I simply trying to set some default values in a store and it seems in a Store it's inside a constructor, so it's initialized obviously.

enter image description here


Solution

Problem was solved by moving Store class to isolated file, before it was in the same file as the global store.



Answered By - zishe
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Tuesday

Why does VS code say there is an error with my object property?

 6:56 PM     ecmascript-6, javascript, oop, typescript, typescript-generics     No comments   

Issue

I was testing some code that utilizes objects in TypeScript and noticed that my IDE's IntelliSense was throwing an error for a new property I was trying to add. It states that the property "text" does not exist, here is my code:

// create new object
var thing : Object = new Object();

// Do things
thing.text = "This is a test.";
console.log(thing.text);


// dereference the object
thing = null;

The error is highlighted on the line(s):

thing.text = "This is a test.";
console.log(thing.text);

Why does VS code list this as an error when this is perfectly acceptable code and behavior in JavaScript? Here is the error screenshot from my editor: Error

EDIT: I should note the code does compile into valid JS with tsc and runs just fine, just curious why the error is showing up as it throws me off while writing the code and makes me think there is some problem when there is not. It also notes in tsc's output the same errors, does this language behavior of being able to add and remove properties to objects change from JavaScript to TypeScript?


Solution

Typescript types are not part of your final code. When you build/run your code, there are no types. They're just there for your benefit when programming. So you can write valid code with incorrect types. Typescript will complain, but your code will still run.

When you initialize your variable, you're setting its type to Object. Which is basically {}. It doesn't have any properties. When you try to set a value for thing.text it gives you an error because thing doesn't have any properties.

You have a couple options:

  1. Initialize thing with text:
const thing = { text: "This is a test." };
thing.text = "You can change the value if you want.";
console.log(thing.text);

Note, you don't need to define the type of thing. Typescript knows its type by its value.

  1. Or, Declare a type for thing where text is optional:
type ThingType = {
  text?: string;
};

// or just: const thing: ThingType = {}
const thing: ThingType = new Object();
thing.text = "This is a test.";
console.log(thing.text);


Answered By - Cully
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Saturday

Print getters when and object is printed in typescript

 9:59 AM     javascript, oop, typescript     No comments   

Issue

Is there an option in TypeScript/JavaScript to print an object who has private properties using their getters instead of printing the private properties names.

By example I have this class in TypeScript

class Vehicle {

  constructor(private _brand: string, private _year: number) {}

  get brand(): string {
    return this._brand;
  }

  get year(): number {
    return this._year;
  }

  set year(year: number) {
    this._year = year;
  }

  set brand(brand: string) {
    this._brand = brand;
  }
}

const vehicle: Vehicle = new Vehicle('Toyota', 10);

console.log(vehicle);

I got this

[LOG]: Vehicle: {
  "_brand": "Toyota",
  "_year": 10
} 

But I'm wondering if I can get something like this

[LOG]: Vehicle: {
  "brand": "Toyota",
  "year": 10
} 

Solution

What console.log does varies by environment. If you want to do what you're describing, you'd have to write your own logger function instead, for instance (in JavaScript, but types are fairly easily added) see comments:

function log(obj) {
    // Get the names of getter properties defined on the prototype
    const ctor = obj.constructor;
    const proto = ctor?.prototype;
    const names = new Set(
        proto
            ? Object.entries(Object.getOwnPropertyDescriptors(proto))
                .filter(([_, {get}]) => !!get)
                .map(([name]) => name)
            : []
    );
    // Add in the names of "own" properties that don't start with "_"
    for (const name of Object.keys(obj)) {
        if (!name.startsWith("_")) {
            names.add(name);
        }
    }
    // Create a simple object with the values of those properties
    const simple = {};
    for (const name of names) {
        simple[name] = obj[name];
    }
    // See if we can get a "constructor" name for it, apply it if so
    let objName =
        obj[Symbol.toStringTag]
        || ctor?.name;
    if (objName) {
        simple[Symbol.toStringTag] = objName;
    }
    // Log it
    console.log(simple);
}

Live Example:

"use strict";

function log(obj) {
    // Get the names of getter properties defined on the prototype
    const ctor = obj.constructor;
    const proto = ctor?.prototype;
    const names = new Set(
        proto
            ? Object.entries(Object.getOwnPropertyDescriptors(proto))
                .filter(([_, {get}]) => !!get)
                .map(([name]) => name)
            : []
    );
    // Add in the names of "own" properties that don't start with "_"
    for (const name of Object.keys(obj)) {
        if (!name.startsWith("_")) {
            names.add(name);
        }
    }
    // Create a simple object with the values of those properties
    const simple = {};
    for (const name of names) {
        simple[name] = obj[name];
    }
    // See if we can get a "constructor" name for it, apply it if so
    let objName =
        obj[Symbol.toStringTag]
        || ctor?.name;
    if (objName) {
        simple[Symbol.toStringTag] = objName;
    }
    // Log it
    console.log(simple);
}

class Vehicle {
    constructor(_brand, _year) {
        this._brand = _brand;
        this._year = _year;
    }
    get brand() {
        return this._brand;
    }
    get year() {
        return this._year;
    }
    set year(year) {
        this._year = year;
    }
    set brand(brand) {
        this._brand = brand;
    }
}
const vehicle = new Vehicle('Toyota', 10);
log(vehicle);

Lots of room to tweak that how you like it, that's just a sketch of how you might go about it.



Answered By - T.J. Crowder
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg

Sunday

How would one simplify a state dependent getter, preferrably in a SOLID manner?

 9:03 AM     angularjs, heuristics, javascript, oop     No comments   

Issue

I have an Angular component that uses a type, what would be an easily readable solution to get one data on one case and the other in another?

The component could also be separated in two components, the phone component and the email component, but most of the logic albeit small would be duplicated.

var getContactInfo, hasContactInfo;
if(type === 'email') {
    getContactInfo = function (profile) { return profile.getEmail()};
    hasContactInfo = function (profile) { return profile.hasEmail()};
} else if(scope.type === 'phone') {
    getContactInfo = function (profile) { return profile.getPhone()};
    hasContactInfo = function (profile) { return profile.hasPhone()};
}

Solution

I would probably have used an object mapping the methods depending on the type:

const buildContactInfo = (getContactInfo, hasContactInfo) => ({ getContactInfo, hasContactInfo });

const contactInfoByType = {
  email: buildContactInfo((profile) => profile.getEmail(), (profile) => profile.hasEmail()),
  phone: buildContactInfo((profile) => profile.getPhone(), (profile) => profile.hasPhone())
};

Then, when calling:

const contactInfo = contactInfoByType[type];
if (!contactInfo) {
  throw new Error(`No contact info matched type '${type}'`);
} else {
  contactInfo.hasContactInfo(profile);
  contactInfo.getContactInfo(profile);
}


Answered By - sp00m
Read More
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Older Posts Home

Popular Posts

  • Letting items go off the div in a horizontal list
    Issue I am trying to recreate this concept app's home page with html css only....
  • Scroll capturing not working because the Svelte slot is inside the Drawer component (Header)
    Issue I was searching for a way to scroll to an element in order to trigger an event. I no...
  • npm ci command failing with "Cannot read property '@angular/animations' of undefined"
    Issue While performing docker build for my Angular project, In the npm ci step, I...
  • How to test Input with React Testing Library?
    Issue I am trying to test an input value of Search component via React Testing L...
  • Typescript generating javascript that doesn't work
    Issue Node is not happy about something in the Javascript that TypeScript is gener...
  • Create a DisplayComponent having a display-component selector
    Issue I am asked to create an Angular component named DisplayComponent and having display...
  • Programmatically change input value in Facebook's editable div input area
    Issue I'm trying to write a Chrome Extension that needs to be able to insert a charact...
  • Typescript DiscordJS bot audio stops working after a few seconds of playing
    Issue I am currently facing an issue with playing audio through a bot I made for d...
  • Ionic Capacitor no capacitor.config.json but instead capacitor.config.ts
    Issue I created an Angular/Ionic project with capacitor. Now I wanted to make changes in m...
  • TypeError: Body is unusable - NextJS Server Action POST
    Issue I am using NextJS v14.1.0 and server action in client component. I get the p...

Labels

.d.ts .htaccess .net .net-5 .net-6.0 .net-8.0 .net-core 2-way-object-databinding 2d 3d 3d-model 3d-modelling 960.gs a2hs aar abortcontroller abp abp-framework absolute abstract abstract-class accelerator access-control-allow-origin access-token accessibility accordion ace-editor acfpro ack acronym action actioncable actionsheet active-directory adal adb adblock addeventlistener adfs adjustment adminlte admob adobe-brackets adonis.js adonisjs-ace ads adsense advanced-custom-fields advertisement-server adyen aes aframe ag-grid ag-grid-angular ag-grid-ng2 ag-grid-react aggregation agm agm-core agm-map agora-web-sdk-ng agora.io airbrake airplay airtable ajax ajax.net ajsf ajv alert alexa-skill alexa-skills-kit algebraic-data-types algolia algorithm alias alignment alpine.js alt alt-attribute altbeacon alter amazon-cloudformation amazon-cloudfront amazon-cognito amazon-dynamodb amazon-dynamodb-streams amazon-ec2 amazon-ecr amazon-elastic-beanstalk amazon-glacier amazon-iam amazon-rds amazon-s3 amazon-sns amazon-sqs amazon-vpc amazon-web-services amcharts amcharts4 amcharts5 amp-html ampersand amplify amplifyjs amplitude-analytics analytics anchor anchor-scroll anchor-solana android android-10.0 android-11 android-12 android-app-bundle android-appcompat android-build android-chrome android-dark-theme android-emulator android-espresso android-gradle-plugin android-intent android-location android-night-mode android-permissions android-sdk-tools android-softkeyboard android-spannable android-sqlite android-studio android-studio-4.2 android-toast android-tv android-vibration android-view android-webview androidx angle angular angular-abstract-control angular-activatedroute angular-akita angular-animations angular-auth-oidc-client angular-auxiliary-routes angular-binding angular-bootstrap angular-bootstrap-calendar angular-breadcrumb angular-broadcast angular-builder angular-cache angular-calendar angular-cdk angular-cdk-drag-drop angular-cdk-overlay angular-cdk-virtual-scroll angular-changedetection angular-chart angular-chosen angular-cli angular-cli-v6 angular-cli-v8 angular-cli-v9 angular-compiler angular-compiler-cli angular-component-life-cycle angular-component-router angular-components angular-config angular-content-projection angular-controller angular-controlvalueaccessor angular-cookies angular-custom-validators angular-dart angular-datatables angular-date-format angular-daterangepicker angular-decorator angular-dependency-injection angular-devkit angular-di angular-directive angular-dom-sanitizer angular-dragdrop angular-dynamic-components angular-dynamic-forms angular-e2e angular-elements angular-errorhandler angular-eslint angular-event-emitter angular-factory angular-file-upload angular-filters angular-flex-layout angular-fontawesome angular-formbuilder angular-formly angular-forms angular-fullstack angular-google-maps angular-gridster2 angular-guards angular-highcharts angular-http angular-http-interceptors angular-httpclient angular-httpclient-interceptors angular-hybrid angular-i18n angular-in-memory-web-api angular-inheritance angular-injector angular-input angular-ivy angular-jest angular-json angular-kendo angular-language-service angular-lazyloading angular-leaflet-directive angular-library angular-lifecycle-hooks angular-load-children angular-local-storage angular-localize angular-maps angular-material angular-material-15 angular-material-5 angular-material-6 angular-material-7 angular-material-datetimepicker angular-material-paginator angular-material-stepper angular-material-table angular-material-theming angular-material2 angular-migration angular-mock angular-module angular-module-federation angular-moment angular-nativescript angular-ng-class angular-ng-if angular-ngfor angular-ngmodel angular-ngmodelchange angular-ngrx-data angular-ngselect angular-nvd3 angular-oauth2-oidc angular-observable angular-output angular-package-format angular-pipe angular-promise angular-providers angular-pwa angular-reactive-forms angular-renderer angular-renderer2 angular-resolver angular-resource angular-route-guards angular-router angular-router-events angular-router-guards angular-router-params angular-routerlink angular-routing angular-schema-form angular-schematics angular-seed angular-service-worker angular-services angular-signals angular-slickgrid angular-social-login angular-socket-io angular-spectator angular-ssr angular-standalone-components angular-state-managmement angular-storybook angular-strap angular-structural-directive angular-template angular-template-form angular-template-variable angular-test angular-testing-library angular-theming angular-toastr angular-tour-of-heroes angular-transfer-state angular-translate angular-tree-component angular-trix angular-ui angular-ui-bootstrap angular-ui-grid angular-ui-modal angular-ui-router angular-ui-router-extras angular-ui-select angular-ui-tree angular-ui-typeahead angular-unit-test angular-universal angular-upgrade angular-validation angular-validator angular-webpack angular10 angular11 angular12 angular13 angular14 angular14upgrade angular15 angular16 angular17 angular2-animation angular2-aot angular2-changedetection angular2-cli angular2-components angular2-custom-pipes angular2-databinding angular2-decorators angular2-di angular2-directives angular2-form-validation angular2-formbuilder angular2-forms angular2-google-maps angular2-guards angular2-highcharts angular2-hostbinding angular2-http angular2-material angular2-meteor angular2-modules angular2-moment angular2-nativescript angular2-ngcontent angular2-ngmodel angular2-observables angular2-pipe angular2-providers angular2-router angular2-router3 angular2-routing angular2-select angular2-services angular2-styleguide angular2-template angular2-testing angular2-toaster angular2-ui-bootstrap angular2-universal angular2viewencapsulation angular4 angular4-aot angular4-forms angular4-router angular5 angular6 angular7 angular8 angular9 angularbuild angulardraganddroplists angularfire angularfire2 angularjs angularjs-1.5 angularjs-1.6 angularjs-authentication angularjs-bindings angularjs-bootstrap angularjs-compile angularjs-components angularjs-controller angularjs-controlleras angularjs-digest angularjs-directive angularjs-e2e angularjs-filter angularjs-forms angularjs-google-maps angularjs-http angularjs-interpolate angularjs-log angularjs-material angularjs-module angularjs-ng-change angularjs-ng-checked angularjs-ng-class angularjs-ng-click angularjs-ng-disabled angularjs-ng-form angularjs-ng-href angularjs-ng-if angularjs-ng-init angularjs-ng-model angularjs-ng-repeat angularjs-ng-route angularjs-ng-show angularjs-ng-switch angularjs-ng-transclude angularjs-ng-value angularjs-ngmock angularjs-nvd3-directives angularjs-orderby angularjs-q angularjs-resource angularjs-routing angularjs-scope angularjs-select angularjs-service angularjs-slider angularjs-templates angularjs-timeout angularjs-track-by angularjs-validation angularjs-watch angulartics animate-on-scroll animate.css animated animation anime.js annotations anonymous anonymous-function ansible ant-design-pro ant-media-server antd antialiasing antora antplus antv any aos.js aot apache apache-echarts apache-fop apache-kafka apache-spark apache-superset apache-zeppelin apache2 apex apexcharts api api-design api-gateway api-key apk apollo apollo-angular apollo-client apollo-server app-initializer app-router app-service-environment app-store appbar appdata appearance append appendchild appery.io appium appium-android apple-app-site-association apple-m1 apple-push-notifications applepay applepay-web applepayjs application-server apply aptana arabic arcgis-js-api architecture argument-passing arguments aria-role arima arquero array-filter array-merge array-reduce array-splice arraybuffer arraylist arrayobject arrayofarrays arrays arrow-functions arrow-keys article asar ascii asp-net-core-spa-services asp.net asp.net-ajax asp.net-core asp.net-core-2.0 asp.net-core-2.1 asp.net-core-3.1 asp.net-core-6.0 asp.net-core-7.0 asp.net-core-8 asp.net-core-css-isolation asp.net-core-identity asp.net-core-mvc asp.net-core-razor-pages asp.net-core-signalr asp.net-core-webapi asp.net-identity asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 asp.net-mvc-5 asp.net-web-api asp.net-web-api-routing asp.net-web-api2 aspect-ratio aspnetboilerplate aspnetcore-environment assets assign astro astrojs async-await async-pipe asynchronous asynchronous-javascript atom-editor attachment attr attributes audio audio-streaming audiocontext audiotrack augmented-reality auth-guard auth0 auth0-connection authentication authority authorization authorize.net autocomplete autofill autofocus autogrow automated-tests automatic-ref-counting automation automation-testing autonumeric.js autoplay autoprefixer autoresize autosize autosuggest avatar avif awk aws-amplify aws-amplify-cli aws-amplify-vue aws-api-gateway aws-appsync aws-cdk aws-cdk-typescript aws-chatbot aws-cloudformation aws-cloudformation-custom-resource aws-code-deploy aws-codeartifact aws-codebuild aws-codepipeline aws-lambda aws-sam aws-sdk aws-sdk-js aws-secrets-manager aws-security-group aws-serverless aws-ssm aws-step-functions aws-userpools axes axios axis-labels azure azure-active-directory azure-ad-b2c azure-ad-b2c-custom-policy azure-ad-graph-api azure-ad-msal azure-api-management azure-application-insights azure-application-insights-profiler azure-appservice azure-blob-storage azure-cdn azure-cosmosdb azure-cosmosdb-sqlapi azure-devops azure-devops-extensions azure-devops-rest-api azure-functions azure-maps azure-notificationhub azure-pipelines azure-pipelines-yaml azure-signalr azure-static-web-app azure-static-website-hosting azure-storage azure-virtual-machine azure-virtual-network azure-web-app-service b2b babel-jest babel-loader babel-plugin-react-css-modules babeljs back back-button backbone-events backbone.js backdrop backend background background-clip background-color background-image background-size backstage badge bamboo banner bar-chart barcode-scanner base-tag base58 base64 base64url bash basic-authentication batch-file batch-processing bazel bdd bearer-token beautifulsoup beego behaviorsubject bem bigcartel bigint biginteger binance binance-api-client binary bind binding bing bing-maps bitbucket bitbucket-pipelines bitmap blade blazor blazor-hybrid blazor-server-side blazor-webassembly blazorise blending blob block blockchain blockly blockquote blogdown blogger blogs bluebird bluetooth bluetooth-lowenergy blur bnf body-parser boilerplate bokeh bold boolean boolean-logic boost-propertytree bootbox bootstrap-3 bootstrap-4 bootstrap-5 bootstrap-5.1 bootstrap-accordion bootstrap-cards bootstrap-carousel bootstrap-datepicker bootstrap-datetimepicker bootstrap-icons bootstrap-modal bootstrap-popover bootstrap-select bootstrap-table bootstrap-tags-input bootstrap-vue bootstrap5-modal border border-box border-image border-radius border-spacing botframework bottomnavigationview bower box box-shadow brain.js braintree branch breadcrumbs break breakpoints brightcove brightness broadcast browser browser-cache browser-detection browser-history browser-support browser-sync browser-tab browserstack bryntum-scheduler brython bubble-sort buffer build build-automation build-definition build-error build.gradle builtwith bull.js bullmq bulma bun bundler bundling-and-minification button buttonclick buttongroup buybutton.js c c# c#-4.0 c++ cache-control caching cakephp calc calculation calculator calendar calendly call callback callkit callstack camelcasing camera camera-api canactivate canactivatechild candeactivate cannon.js canvas capacitor capacitor-plugin capitalization capitalize capslock captcha caption capture capturestream capturing-group carbon-design-system card caret cargo carousel carriage-return cart cas case casting catalyst cdn cell center centering centos cgi cgi-bin chai chai-as-promised chakra-ui chalk change-detector-ref character character-encoding chart.js chart.js2 chartjs-2.6.0 chartjs-plugin-zoom charts chat chatbot checkbox checked checkmarx checkout cheerio child-process children chinese-locale chm choicesjs chord chrome-custom-tabs chrome-extension-manifest-v3 chromium chron chunking cicd circular-dependency citations cjk ckeditor ckeditor4.x ckeditor5 claims-authentication clasp class class-attributes class-names class-transformer class-validator classname clean-architecture clearfix clerk click clickable client client-side client-side-attacks client-side-validation clip clip-path clipboard clipping clock clone clonenode cloning closures cloud cloud-foundry cloudflare cloudinary cmd cocoapods code-coverage code-formatting code-generation code-injection code-push code-reuse code-signing code-translation codegen codehooks.io codeigniter codeigniter-3 codeigniter-restserver codelyzer codenameone codepen codesandbox coding-style coffeescript col collapsable collapse collation collect collections colon color-blending color-picker color-scheme color-space colors column-chart column-count column-width combinelatest combo-chart combobox cometchat command-line command-line-interface comments commonjs communication comobject compare comparison compass compass-sass compatibility compilation compile-time compiler-errors compiler-options compiler-warnings complextype component-store components compound-operator computed-properties computer-science computer-vision concatenation concatmap concurrently conditional conditional-compilation conditional-formatting conditional-operator conditional-rendering conditional-statements conditional-types config config.json configuration confirm confirm-dialog conflict connect-four connectivity console console.log constants constraint-validation-api constructor constructor-overloading contact contact-form-7 container-queries containers contains content-management-system content-security-policy content-type contenteditable contentproperty context-api contextmenu contextpath continuous-integration contrast contravariance controller controlvalueaccessor conventions converters cookies copy copy-constructor copy-paste cordova cordova-2.0.0 cordova-3 cordova-android cordova-ios cordova-plugin-advanced-http cordova-plugin-fcm cordova-plugin-firebasex cordova-plugin-proguard cordova-plugins core-js core-web-vitals correlation cors cors-anywhere couchdb countdown covariance cpanel cpu cpu-word crash create-react-app createcontext createelement createjs cron cropperjs cross-browser cross-domain cross-origin-read-blocking cross-origin-resource-policy cross-platform cross-window-scripting crt crud cryptography cryptojs cs50 csp csproj csrf csrf-token css css-animations css-calc css-cascade css-content css-counter css-filters css-float css-functions css-gradients css-grid css-houdini css-hyphens css-import css-in-js css-layer css-loader css-mask css-modules css-multicolumn-layout css-position css-print css-reset css-selectors css-shapes css-specificity css-sprites css-tables css-transforms css-transitions css-variables cssnano cssom csv cucumber cucumberjs cufon cumulative-layout-shift cups curl currency currency-formatting currency-pipe currying cursor curve custom-attributes custom-build custom-button custom-component custom-controls custom-cursor custom-data-attribute custom-directive custom-domain custom-element custom-font custom-post-type custom-type customization customvalidator cypress cypress-component-test-runner cypress-conditional-testing cypress-cucumber-preprocessor cypress-each d3-dag d3.js d3tree daisyui danfojs dangerouslysetinnerhtml darkmode dart dart-html dart-sass dashboard data-binding data-conversion data-retrieval data-structures data-transform data-uri data-visualization database database-migration dataframe datagrid datalist datasource datatable datatables date date-fns date-format date-formatting date-pipe date-range datepicker daterangepicker datetime datetime-format datetimepicker dayjs days deadline-timer debian debounce debouncing debugging decentralized-applications decimal decimalformat deck.gl declaration declarative declarative-programming declare decoder decoding decorator deep-copy deep-linking deeplink default default-value deferred deferred-loading defineproperty definitelytyped definition delay delegates deno denodb dependencies dependency-injection dependency-management deploying deployment deprecated descendant deserialization design-patterns desktop desktop-application destructuring details-tag detection dev-to-production developer-tools development-environment devexpress devextreme devextreme-angular device device-detection device-orientation devise devops devtools dexie dexiejs dhtml dhtmlx diagonal diagram dialog dictionary diff difference digital-ocean digital-signature dijit.layout directive directory directory-structure dirpagination disable disabled-control disabled-input discord discord.js discriminated-union dispatch display displayobject displaytag disqus distinct-values divi divi-theme divider division django django-admin django-celery django-crispy-forms django-csrf django-extensions django-filter django-forms django-models django-rest-framework django-templates django-views django-weasyprint django-webpack-loader djangocms-text-ckeditor dji-sdk dns docfx docker docker-compose docker-swarm dockerfile doctype document document-ready documentation dojo dom dom-events dom-manipulation dom-to-image domain-driven-design domain-name domdocument domparser dompdf donut-chart dotenv dotnetnuke download drag drag-and-drop draggable drake draw drawimage drawing drizzle drop-down-menu dropdown dropdownbox dropshadow dropzone.js drupal dry dspace dt dto duplicates durandal duration dwr dx-data-grid dynamic dynamic-arrays dynamic-data dynamic-html dynamic-import dynamic-programming dynamic-routing dynamic-values dynamically-generated dynamicgridview dynamics-crm dynamics-marketing dynamodb-queries e-commerce e2e e2e-testing each eager-loading easeljs easy-peasy echarts echo eclipse ecma ecmascript-2016 ecmascript-2017 ecmascript-2019 ecmascript-2020 ecmascript-5 ecmascript-6 ecmascript-next editor editorconfig editorjs effect effects ej2-gantt ej2-syncfusion ejs el-plus elastic-stack elasticsearch electron electron-builder electron-forge electron-packager element element-plus element-ui elementor elementref elementtree elixir elk ellipse ellipsis elm elysiajs emacs email email-attachments email-confirmation email-formats email-templates email-validation embed embedded-fonts ember.js emitter emmet emoji emojione emotion empty-list emulation encapsulation encoding encryption end-to-end endpoint enjoyhint enter enterprise entities entity entity-framework entity-framework-core enums environment environment-variables enzyme eos epub equivalent erase erb error-handling es6-class es6-module-loader es6-modules es6-promise esbuild escaping escpos eslint eslint-config-airbnb eslintrc esmodules esri esri-maps ethereum euro event-binding event-driven event-handling event-listener event-loop event-propagation eventemitter events eventstoredb excel excel-addins excel-formula excel-online excel-web-addins excel4node exceljs exception execcommand exif-js expand expandable-table expansion expo expo-sqlite export export-to-csv export-to-excel express express-handlebars express-session extend extending extends external external-js external-url extjs extract fabricjs facade facebook facebook-comments facebook-graph-api facebook-ios-sdk facebook-javascript-sdk facebook-login facebook-opengraph facebook-sharer facebook-social-plugins facelets factory factory-pattern fade fadein failed-installation faker.js fallback fancybox farsi fast-xml-parser fastapi fastcgi fastify fastlane faunadb favicon fetch fetch-api ffmpeg fido figma figure file file-io file-link file-not-found file-structure file-upload fileapi filelist filenames filepath filereader files-app filesaver.js filesystems filetree filter filtering final find findall findelement fingerprint firebase firebase-admin firebase-analytics firebase-app-check firebase-authentication firebase-cli firebase-cloud-messaging firebase-console firebase-dynamic-links firebase-extensions firebase-hosting firebase-notifications firebase-realtime-database firebase-security firebase-storage firebase-tools firebaseui firebug fireflysemantics-slice firefox firefox-addon firefox-addon-webextensions firefox-developer-tools firefox4 firewall fixed fixed-length-array fixed-width fixtures flash flask flask-autoindex flask-cors flask-mail flask-restful flask-socketio flask-sqlalchemy flask-wtforms flatpickr flex3 flexbox flexdashboard flexslider flextable flicker flickity flickr flip floating-action-button flowbite flower fluent-ui fluentui-react fluentvalidation fluid fluid-layout flutter flutter-test flutter-web flying-saucer focus folium font-awesome font-awesome-4 font-awesome-5 font-awesome-6 font-face font-family font-size fonts footer for-in-loop for-loop foreach foreground-service foregroundnotification foreignobject forgerock forgot-password fork-join form-control form-data form-fields form-submit form-verification formarray format formatdatetime formatting formbuilder formgroups formik formio formmail forms formula forward-reference forwarding foundation foundry-slate fp-ts fpm fragment framer-motion frameset frameworks freemarker freeze freshjs froala frontend frontpage fs full-width fullcalendar fullcalendar-3 fullcalendar-4 fullcalendar-5 fullcalendar-6 fullcalendar-scheduler fullscreen function function-call function-parameter functional-programming fusioncharts fxml gallery game-development gantt-chart garbage-collection gatsby gatsby-plugin-mdx gauge gcloud gdi+ generator generic-function generic-type-argument generic-type-parameters generics geojson geolocation geometry geonames geoserver gesture get getattribute getcomputedstyle getdate getelementbyid getelementsbyclassname getelementsbytagname getimagesize getter getter-setter getuikit getusermedia getvalue gherkin ghost-blog gif gis git git-bash git-diff git-husky gitbook github github-actions github-api github-flavored-markdown github-pages gitignore gitlab gitlab-ci gitlab-ci-runner global global-variables glyphicons gmail gmail-api go go-echo gojs golden-layout google-admin-sdk google-ads-api google-analytics google-analytics-4 google-analytics-api google-api google-api-java-client google-api-js-client google-app-engine google-apps-marketplace google-apps-script google-authentication google-calendar-api google-chrome google-chrome-console google-chrome-devtools google-chrome-extension google-chrome-headless google-chrome-warning google-cloud-build google-cloud-firestore google-cloud-functions google-cloud-platform google-cloud-pubsub google-cloud-scheduler google-cloud-sql google-cloud-storage google-cloud-vertex-ai google-colaboratory google-compute-engine google-developer-tools google-dfp google-diff-match-patch google-docs google-docs-api google-drive-api google-finance-api google-font-api google-fonts google-forms google-geolocation google-index google-login google-map-react google-maps google-maps-api-3 google-maps-autocomplete google-maps-markers google-material-icons google-oauth google-one-tap google-pagespeed google-places-api google-play google-play-billing google-play-console google-play-services google-plus google-plus-signin google-reviews google-roads-api google-search google-secret-manager google-sheets google-signin google-street-view google-street-view-static-api google-tag-manager google-text-to-speech google-translate google-visualization google-web-designer google-webfonts google-workspace googleplacesautocomplete gps gradient gradle grammar graph graphical-logo graphics graphql graphql-codegen graphql-js graphql-mutation graphviz gravatar gravity grayscale greasemonkey grecaptcha grep grid grid-layout gridstack gridster gridview groovy group-by grouping grpc grpc-js grpc-node grpc-web gruntjs gsap gsub gtag.js gtk gtk3 guard guid guidewire gulp gulp-imagemin gulp-sass gulp-typescript gulp-uglify gun gutenberg-blocks gwt h2 hamburger-menu hammer.js hana handle handlebars.js handsontable hapi hapijs hardhat hardware hash hash-location-strategy hashbang hashmap hashtag hbs hdiv hdpi header headless-cms headless-ui heads-up-notifications heatmap heic height helmet.js helper heroku heuristics hex hibernate hidden hide hierarchy highcharts highcharts-gantt higher-order-components higher-order-functions highlight highlight.js highlighting histogram history history.js hls.js home-button hono hook hook-woocommerce horizontal-alignment horizontal-scrolling host hosting hot-module-replacement hot-reload hotkeys hover href hsl htdocs html html-agility-pack html-content-extraction html-datalist html-email html-encode html-entities html-frames html-framework-7 html-head html-heading html-helper html-imports html-injections html-input html-lists html-parsing html-pdf html-rendering html-sanitizing html-select html-table html-tbody html-templates html-to-pdf html-validation html-webpack-plugin html.actionlink html2canvas html2pdf html4 html5-audio html5-canvas html5-draggable html5-filesystem html5-history html5-template html5-video htmlcollection htmlelements htmllint htmlspecialchars htmltools htmlunit htmx http http-accept-language http-delete http-equiv http-error http-get http-headers http-live-streaming http-options-method http-parameters http-patch http-post http-proxy http-proxy-middleware http-status-code-400 http-status-code-401 http-status-code-404 http-status-code-405 http-status-code-415 http-status-code-500 http-status-code-503 http-status-codes http2 httpbackend httpclient httpcontext httpcookie httpexception httpinterceptor httprequest httpresponse https httpserver httpwebrequest httpwebresponse httr huawei-mobile-services hugo husky hybrid-mobile-app hybris hydration hyperledger-composer hyperledger-fabric hyperlink hyperscript hyphen hyphenation i18next ibeacon icecast ico icon-fonts icons id3 ide identityserver3 identityserver4 idioms idp ienumerable if-statement ifc iframe iframe-resizer ignite-ui iife iis iis-10 iis-7 iis-7.5 iis-8 iisnode image image-cropper image-gallery image-processing image-resizing image-scaling image-size image-slider imagemap imagepicker imageset imaskjs imei imgur immutability immutable.js implements import import-from-excel importerror in-app-purchase inappbrowser include increment indentation index-signature indexeddb indexing indexof inertiajs inference infinite-scroll influxdb info information-visualization infragistics inheritance init initialization initializer inject injectable injection-tokens inline inline-styles inline-svg inner-classes innerhtml innertext input input-mask input-type-file inputbox inputevent inquirer insert inspect instagram installation instance instanceof integer integration intellij-idea intellisense interact.js intercept interceptor interface internationalization internet-explorer internet-explorer-11 internet-explorer-6 internet-explorer-7 internet-explorer-8 internet-radio interpolation intersection intersection-observer intersection-types intl-tel-input intrinsicattributes intro.js invariance inversion-of-control invisible-recaptcha invokescript ion-checkbox ion-content ion-grid ion-infinite-scroll ion-item ion-menu ion-radio-group ion-range-slider ion-segment ion-select ion-slides ion-toggle ionic ionic-appflow ionic-cli ionic-cordova ionic-enterprise-auth ionic-framework ionic-native ionic-native-http ionic-plugins ionic-popover ionic-popup ionic-react ionic-storage ionic-tabs ionic-v1 ionic-view ionic-vue ionic-webview ionic2 ionic2-calendar ionic3 ionic4 ionic5 ionic6 ionic7 ionicons ios ios-camera ios-permissions ios-simulator ios10 ios11 ios13 ios15 ip ipad ipc ipcmain ipconfig ipcrenderer iphone iphone-standalone-web-app ipython isnull iso8601 isodate istanbul itemcontainerstyle iter-ops iteration iterm2 itext itext7 itfoxtec-identity-saml2 itms-90809 itunes-search-api ivy jackson jaeger jakarta-ee jar jasmin jasmine jasmine-marbles jasmine-ts jasmine2.0 java java-8 javafx javafx-8 javascript javascript-debugger javascript-decorators javascript-framework javascript-import javascript-marked javascript-objects javascript-proxy jaws-screen-reader jdl jeditorpane jekyll jenkins jenkins-pipeline jersey jest-dom jest-preset-angular jestjs jhipster jinja2 jinja2-cli jira jira-rest-api jodit joi join joomla jose jpa jpeg jquery jquery-animate jquery-autocomplete jquery-deferred jquery-events jquery-lazyload jquery-masonry jquery-mobile jquery-plugins jquery-select2 jquery-selectors jquery-terminal jquery-ui jquery-ui-button jquery-ui-datepicker jquery-ui-dialog jquery-ui-draggable jquery-ui-menu jquery-ui-selectable jquery-ui-slider jquery-ui-sortable jquery-validate jqxgrid js-routes js-scrollintoview js-xlsx js-yaml jsbarcode jsbundling-rails jscompress jscontext jsdoc jsdom jsencrypt jsf jsf-2 jsfiddle jsgrid jshint json json-api json-ld json-schema-validator json-server json.net json2html json5 jsoneditor jsonidentityinfo jsonp jsonplaceholder jsonschema jsoup jsp jsp-tags jspdf jspdf-autotable jspsych jsrender jsreport jss jstl jstree jsx jszip jtable junit jupyter jupyter-notebook justify jvectormap jwplayer jwt kable kableextra karma-coverage karma-jasmine karma-mocha karma-runner kebab-case kendo-chart kendo-combobox kendo-datepicker kendo-dropdown kendo-grid kendo-ui kendo-ui-angular2 kendo-upload kepler.gl keras kestrel key key-bindings key-value keyboard keyboard-events keyboard-navigation keyboard-shortcuts keycloak keycloak-js keycloak-rest-api keycloak-services keycode keydown keyframe keyof keypress keyup keyword kibana-4 kill kill-process kineticjs knex.js knitr knockout.js koa koa-bodyparser kong konva konvajs kotlin kramdown kubernetes kubernetes-ingress label labels lagom lambda lan lang language-design language-lawyer language-server-protocol laravel laravel-4 laravel-5 laravel-5.3 laravel-5.8 laravel-8 laravel-9 laravel-blade laravel-breeze laravel-livewire laravel-passport laravel-sanctum laravel-snappy laravel-validation lastpass late-binding latex layer layout lazy-initialization lazy-loading leaderboard leaflet leaflet-geoman leaflet.draw less lets-encrypt letter-spacing lexicaljs libphonenumber libraries lifecycle ligature lightbox lightbox2 lightgallery lighthouse limit line line-breaks line-height line-through linear-gradients linechart linefeed linkedin-api linksys linq linq-to-sql lint lint-staged linter linux liquid liskov-substitution-principle list listbox listener listitem listjs listobject listpicker listview lit lit-element lit-html literals live live-streaming livereload liveserver load load-balancing load-order loader loading local local-storage localdate locale localhost localization localnotification location-href lodash logentries logging logic login login-page login-system logout logstash long-press loopback loopbackjs loops lottie lowercase lucid lumen luxon lxml lynx m3u m3u8 mac-address macos macos-big-sur macos-catalina macos-high-sierra macos-monterey macros magento magento2 magnific-popup mailchimp-api-v3.0 mailto makestyles mako manifest manifest.json many-to-many map mapbox mapbox-gl mapbox-gl-js mapped-types mapper mapping maps margin margins markdown markerclusterer markup marp marpit marquee mask masking masonry master-detail master-pages mat mat-autocomplete mat-card mat-datepicker mat-dialog mat-drawer mat-error mat-expansion-panel mat-form-field mat-icon mat-input mat-list mat-option mat-pagination mat-select mat-sidenav mat-slider mat-stepper mat-tab mat-table match material-components material-components-web material-design material-design-lite material-dialog material-icons material-table material-ui materialbutton materialize math math-functions mathematical-expressions mathjax mathml matter.js maven max maxlength mcu md-autocomplete md-select mdbootstrap mdc-components mddialog mean mean-stack meanjs measurement mechanize media media-queries mediastream megamenu memoization memoized-selectors memory memory-leaks memory-management mention menu menubar menuitem mercurius merge mergemap mern mesh message meta meta-tags metadata metamask metaplex meteor meteor-blaze methods metrics metro-bundler micro-frontend microservices microsoft-edge microsoft-graph-api microsoft-identity-platform microsoft-teams microsoft-web-deploy middleware midi migration mikro-orm milvus mime mime-message mime-types mindmap minesweeper minify minimist minio minmax miragejs mithril.js mix-blend-mode mixins mjml mkdocs mobile mobile-angular-ui mobile-application mobile-browser mobile-development mobile-safari mobile-website mobx mobx-react mobx-state-tree mocha-webpack mocha.js mocking mod-rewrite modal-dialog modal-sheet modal-window modalviewcontroller model model-binding model-view-controller model-viewer modifier modular-design module moment-timezone momentjs monaco-editor mongodb mongodb-query mongoid mongoose mongoose-middleware mongoose-schema monorepo monospace monthcalendar moodle mootools mosaic motorola mouse-cursor mouseevent mousehover mouseleave mousemove mouseover mousewheel moving-average mozilla mp3 mp4 mpd mpdf mpmediaquery mqtt ms-access ms-office ms-word msal msal-angular msal.js msbuild msgpack mudblazor mui5 muipickersutilsprovider multer multer-gridfs-storage multer-s3 multi-level multi-page-application multi-select multi-tenant multi-user multidimensional-array multiline multipage multipart multipartfile multipartform-data multiple-columns multiple-inheritance multiple-instances multiplication mutable mutation-observers mvvm mvw mxgraph mysql mysqli namecheap namespaces naming-conventions nan nanoid narrowing native native-base native-web-component nativescript nativescript-angular nativescript-plugin nativescript-telerik-ui nativescript-vue nav nav-pills navbar navigateurl navigation navigation-drawer navigationbar navigationcontroller navigator nebular nedb nest nest-commander nested nested-json nested-lists nested-loops nested-object nestjs nestjs-config nestjs-jwt nestjs-swagger netbeans netlify netsuite network-efficiency new-operator new-project new-window newline newsletter next next-auth next-images next-link next.js next.js13 next.js14 nextjs-dynamic-routing nextjs-image nexus nexus-js nexus-prisma nfc nft ng ng-animate ng-apexcharts ng-bootstrap ng-build ng-class ng-component-outlet ng-container ng-content ng-controller ng-deep ng-dialog ng-file-upload ng-filter ng-flow ng-grid ng-hide ng-image-compress ng-map ng-messages ng-mocks ng-modal ng-modules ng-multiselect-dropdown ng-options ng-otp-input ng-packagr ng-pattern ng-repeat ng-required ng-select ng-show ng-storage ng-style ng-submit ng-switch ng-tags-input ng-template ng-upgrade ng-view ng-zorro-antd ng2-bootstrap ng2-charts ng2-redux ng2-smart-table ng2-translate ngb-datepicker ngcordova ngfor nginfinitescroll nginx nginx-cache nginx-config nginx-location nginx-reverse-proxy ngmock ngmodel ngonchanges ngondestroy ngoninit ngresource ngrok ngroute ngrx ngrx-component-store ngrx-data ngrx-effects ngrx-entity ngrx-reducers ngrx-router-store ngrx-selectors ngrx-store ngrx-store-4.0 ngtable ngtemplateoutlet ngu-carousel ngx-admin ngx-bootstrap ngx-bootstrap-modal ngx-bootstrap-popover ngx-charts ngx-chips ngx-cookie-service ngx-datatable ngx-daterangepicker-material ngx-drag-drop ngx-echarts ngx-extended-pdf-viewer ngx-formly ngx-image-cropper ngx-international-phone-number ngx-leaflet ngx-mask ngx-monaco-editor ngx-mydatepicker ngx-pagination ngx-paypal ngx-quill ngx-restangular ngx-socket-io ngx-spinner ngx-swiper-wrapper ngx-toastr ngx-translate ngx-translate-multi-http-loader ngx-ui-loader ngxs nightwatch.js nl2br nlp noborder node-commander node-config node-fetch node-gyp node-modules node-red node-redis node-sass node-sqlite3 node-streams node-webkit node.js node.js-addon node.js-connect nodelist nodemailer nodemon nodes noise nokogiri nomachine-nx nominatim normalization normalize-css noscript nosql notepad++ notifications notify nouislider npm npm-build npm-install npm-link npm-live-server npm-package npm-publish npm-run npm-scripts npm-start npm-update npm-version npm-vulnerabilities npx nrwl nrwl-nx nsattributedstring nsstring nuget null null-check nullable number-formatting numbers nuxt.js nuxt3 nuxtjs3 nvd3.js nvda nvm nwjs nx-devkit nx-workspace nx.dev nyc oak oauth oauth-2.0 obfuscation object object-destructuring object-fit object-literal object-position object-property objective-c objloader observable observers ocelot odata odometer odoo odoo-13 odoo-15 oembed office-addins office-app office-js office-scripts office365 offline offline-caching offset ohif oidc-client okhttp okta on-screen-keyboard onbeforeunload onblur onchange onclick onclicklistener one-trust onedrive onerror onesignal onfocus onhover onload onmousedown onmouseover onsen-ui onsubmit oop opacity opayo open-telemetry openapi openapi-generator opencart opencart2.3 opencv opendatasoft openid openid-connect openlayers openlayers-5 openlayers-6 openstreetmap opentype-svg-font openvidu openweathermap opera operating-system operators opine optgroup optimization option option-type optional optional-chaining optional-parameters options oracle oracle-apex orchardcms orchardcore org-mode orientation-changes orm orphan out outdir outline outlook outlook-2010 outlook-2016 output overflow overlap overlapping overlay overloading overriding owasp owl-carousel owl-carousel-2 owl-date-time p-dropdown p-table p2p p5.js pack package package-info package-managers package.json pact padding page-break page-break-before page-layout page-load-time page-refresh pageload pageobjects pagespeed pagespeed-insights pagination paginator paging paint palantir-foundry palindrome pandas pandas-styles pandoc pane panel pannellum panning panzoom papaparse paragraph parallax parallel-processing parameter-passing parameters parcel parceljs parent parent-child parse-platform parseint parsel parsing partial partial-classes partial-views partials particles particles.js pass-by-reference pass-by-value passport-azure-ad passport-jwt passport-local passport.js password-protection passwords patch patch-package patchvalue path pattern-matching payment-gateway payment-method paypal pdf pdf-form pdf-generation pdf-viewer pdf.js pdfjs-dist pdfmake peer-dependencies peerjs pelco penetration-testing percentage performance perl permalinks permissions permutation perspective pg-promise phantom-types phantomjs phaser phaser-framework phaserjs phoenix-framework phone-call phonegap phonegap-build phonegap-plugins photo photography php phpmailer phppresentation phpstorm phpstorm-2017.1 physics-engine picasa pick picklist picture-element picturefill pie-chart pikaday pinchzoom ping pinia pinterest pipe pipeline pipes-filters pixel pixi.js pkce pkgdown placeholder plaintext play-billing-library playframework playframework-2.0 playwright playwright-test playwright-typescript plesk plot plotly plotly-dash plotly-express plotly-python plotly.js plsql plugins plyr.js pm2 png pnp-js pnpm pointer-events pointers pokeapi polling polyfills polyglot-markup polygon polymer polymorphism popover populate popup popupwindow port portfolio porting portrait position positional-operator positioning post postcss postcss-cli poster postgis postgresql postgresql-9.5 postman pouchdb power-automate power-automate-desktop powerbi powerbi-embedded powerpoint powershell powershell-core pre pre-commit-hook pre-rendering precompile predicate preflight preg-match preg-replace preload preloader preloading preprocessor prerender prestashop prestashop-1.7 prettier pretty-print prettytable preventdefault preview primefaces primeflex primeicons primeng primeng-calendar primeng-datatable primeng-dialog primeng-dropdowns primeng-menu primeng-table primeng-tree primeng-turbotable primereact primevue printing printing-web-page printthis prism.js prisma prisma-graphql prisma-orm prisma2 prismic.io privacy private private-constructor processing product production production-environment profiler progress progress-bar progressive-enhancement progressive-web-apps proj project projection promise prompt prop properties property-binding proportions protected proto protocol-buffers protocol-relative prototype prototype-chain prototypejs protractor provider proxy pseudo-class pseudo-element public publish publishing pug pull-to-refresh pulumi punycode puppeteer pure-css pure-function push push-notification pushstate pushy put putimagedata pwa pygments pyodide pyqt pyqt5 pyscript pyscripter pyside2 python python-2.7 python-3.x python-requests python-requests-html python-sphinx pythonanywhere q qlabel qr-code qt qtextedit qtstylesheets qtwebkit quarkus quarkus-rest-client quarto quasar quasar-framework query-builder query-optimization query-parameters query-string queryparam queryselector queue quill quote quotes r r-markdown rabbitmq race-condition rack rackspace radial-gradients radio radio-button radio-group radix-ui radzen railway ramda.js random range rapidapi rasa raspberry-pi rating razor razor-pages razorpay react-18 react-admin react-animated react-big-calendar react-bootstrap react-bootstrap-nav react-chartjs react-chartjs-2 react-class-based-component react-component react-context react-create-app react-css-modules react-custom-hooks react-data-table-component react-datepicker react-dnd react-dom react-dom-server react-dropdown-tree-select react-dropzone react-error-boundary react-fiber react-flow react-forms react-forwardref react-functional-component react-google-charts react-google-recaptcha react-hoc react-hook-form react-hooks react-hooks-testing-library react-i18next react-icons react-infinite-scroll-component react-jsx react-konva react-leaflet react-leaflet-v3 react-map-gl react-material react-mui react-native react-native-android react-native-drawer react-native-firebase react-native-flatlist react-native-gesture-handler react-native-navigation react-native-reanimated react-native-reanimated-v2 react-native-sqlite-storage react-native-stylesheet react-native-testing-library react-native-textinput react-navigation react-navigation-bottom-tab react-navigation-drawer react-navigation-stack react-navigation-v6 react-oauth react-otp-input react-pdf react-phone-input-2 react-phone-number-input react-player react-props react-proptypes react-query react-redux react-rendering react-router react-router-dom react-scripts react-select react-slick react-spring react-state react-state-management react-testing-library react-three-drei react-tooltip react-transition-group react-tsx react-typescript react-usecallback react-usememo reactive reactive-forms reactive-programming reactivex reactjs reactstrap readfile readme readonly real-time real-time-updates reason recaptcha recaptcha-v3 recharts recoiljs record recursion recursive-datastructures redaction redcap redirect redis redoc redocly reduce reducers redux redux-devtools redux-logger redux-observable redux-persist redux-reducers redux-saga redux-thunk redux-toolkit ref refactoring reference referrals referrer-policy reflect-metadata reflection reflow refresh refresh-token regex regex-lookarounds regexp-replace region rel relationship relative-path relative-url release reload remix-auth-socials remix-run remix.run remove-if removing-whitespace rename render renderer rendering renovate reorderlist repeat repeating-linear-gradient replace replaysubject reporting-services request request-headers requestanimationframe require required requiredfieldvalidator requirejs rerender rescript reselect reserved-words reset reset-password resharper resizable resize resolve resources response response-headers responsive responsive-design responsive-design-view responsive-images responsiveness rest rest-parameters restangular restapi restart restful-authentication restrict restructuredtext retina-display return return-type return-value reusability reveal.js reverse reverse-engineering reverse-proxy rgba rgl rich-text-editor richtext rider right-to-left ringcentral riot.js robotframework roboto role-based roles rollup rollup-plugin-postcss rollupjs roman-numerals roslyn rotatetransform rotation round-slider rounded-corners route-provider routeparams router router-outlet routerlink routerlinkactive routes routing row row-height rows rss rstudio rsuite rtcpeerconnection rtk-query rtmp rtos rtsp ruby ruby-characters ruby-on-rails ruby-on-rails-3 ruby-on-rails-4 ruby-on-rails-5 ruby-on-rails-7 rules run-configuration runtime runtime-configuration runtime-error rust rvest rx-angular rxfire rxjs rxjs-filter rxjs-fromevent rxjs-marbles rxjs-observables rxjs-pipeable-operators rxjs-subscriptions rxjs5 rxjs6 rxjs7 safari safe-navigation-operator sails.js salesforce salesforce-communities salesforce-marketing-cloud saml samsung-galaxy samsung-smart-tv sanctum sandbox sanitization sanitizer sap-commerce-cloud sap-fiori sapui5 sass sass-loader sass-maps sass-variables saucelabs save savefiledialog scale scaling scheduled-tasks scheduler schema scope scoping scrapy screen screen-capture screen-orientation screen-readers screen-scraping script script-src script-tag scripting scroll scroll-paging scroll-snap scrollbar scroller scrollmagic scrollspy scrolltop scrolltrigger scrollview scss-functions scss-lint scss-mixins sdk search search-engine search-form searchbar sections secure-coding security sed seek segment select select-options selected selectedindex selectinput selection selection-api selectionmodel selectize.js selector selectors-api selenium selenium-chromedriver selenium-ide selenium-iedriver selenium-webdriver selenium-webdriver-python self-destruction semantic-html semantic-markup semantic-ui semantic-ui-react semantics sencha-touch-2 send sendbeacon sendgrid sendmail sendmessage seo separation-of-concerns sequelize-cli sequelize-typescript sequelize.js sequential serialization serve server server-sent-events server-side-includes server-side-rendering serverless serverless-architecture serverless-framework serverless-framework-step-functions service service-worker servicenow servlets session session-cookies session-storage session-timeout set setattribute setinterval setstate setter settimeout settings sfu sgml sh sha256 shadcnui shader shadow shadow-dom shadow-root shaka shallow-copy shape shape-outside shapes share share-open-graph shared-directory shared-libraries shared-module sharepoint sharepoint-2013 sharepoint-online sharp sheetjs shell shiny shinybs shinyjqui shop shopify shopify-api shopizer shopping-cart shopware6 shortcut shoutcast show show-hide showmodaldialog shuffle siblings side-effects sidebar sidenav sigma.js sign sign-in-with-apple signalr signalr-hub signalr.client signals signature signaturepad sim-card simplemodal sinatra single-page-application single-sign-on single-spa single-spa-angular singleton singularitygs sinon sip sitedesign size sizing skeleton-css-boilerplate skeleton-ui skiasharp slice slick slick.js slickgrid slickgriduniversal slide slider slideshow sliding-tile-puzzle slim slim-4 slim-lang smart-table smartcontracts smil smooth-scrolling smtp smtpjs snackbar snap snapshot-testing snipcart soap social-authentication social-media socialsharing-plugin socket-timeout-exception socket.io socket.io-client sockets sockjs soft-hyphen solana solana-web3js solaris solid-js sonarlint sonarqube sorting soundcloud source-code-protection source-maps spa-template space spaces spacing spartacus-storefront speaker special-characters specifications spectator speech speech-synthesis spfx spfx-extension spinner splash-screen splidejs split splitter spotify spotlight spread spread-syntax spreadjs spring spring-batch spring-boot spring-boot-security spring-cloud spring-cloud-gateway spring-data spring-data-jpa spring-form spring-mvc spring-restcontroller spring-security spring-security-oauth2 spring-security-rest spring-security-saml2 spring-thymeleaf spring-webflux sprite spy spyon sql sql-like sql-server sqlalchemy sqlite squarespace squirrel.windows src srcset ssh2-sftp ssl ssl-certificate ssrs-2012 stack stack-navigator stack-trace stackblitz stacking-context standards startup state state-machine static static-files static-site-generation static-typing static-web-apps statistics status stenciljs step stepper sticky sticky-footer stomp stoppropagation stopwatch storage store storefront storybook str-replace strapi stream streamable.com streaming streaming-video streamlit strict strictnullchecks strikethrough string string-concatenation string-formatting string-interpolation string-literals stringify strip stripe-payments stripes stroke stroke-dasharray strokeshadow strong-typing strpos struct structured-clone struts-1 struts2 stryker style-dictionary styled-components styled-system stylelint styles stylesheet styling stylus stylus-pen subclassing subdirectory subject subject-observer sublime-text-plugin sublimetext sublimetext2 sublimetext3 submenu submit subpixel subscribe subscript subscription substring subtitle sudo sudoku suitescript sum summary-tag summernote supabase supabase-js superscript supertest survey susy-compass svelte svelte-3 svelte-component svelte-store svelte-transition sveltekit svg svg-animate svg-defs svg-filters svg-map svg-morphing svg.js sw-precache swagger swagger-ui sweetalert sweetalert2 swift swiftui swing swipe swipe.js swiper swiper.js swiperjs switch-statement switching switchmap swr symbols symfony symfony-flex symfony4 symfony5 syncfusion synchronization syntax syntax-error syntax-highlighting systemjs t4 tabindex tablecelleditor tablecellrenderer tableheader tablelayout tablet tabmenu tabs tabular tabulator tags tailwind-3 tailwind-css tailwind-elements tailwind-in-js tailwind-ui tampermonkey tanstack tanstackreact-query task tauri tcl tcp tcpdf teamcity teams-toolkit tedious tel telegram telegram-bot telerik telerik-mvc template-engine template-literals templatebinding templates tempus-dominus-datetimepicker tensorflow tensorflow.js tensorflowjs-converter terminal terminology ternary-operator testbed testcafe testing testing-library text text-align text-alignment text-cursor text-decorations text-editor text-extraction text-files text-indent text-size text-to-speech textarea textbox textcolor textfield textinput textnode textout textselection textual textview tfs themes theming thermal-printer thickness thingsboard this this-keyword three.js throttling throw thumbnails thymeleaf tic-tac-toe tiktok tilt time time-series time-tracking timeago timeout timepicker timer timestamp timezone timezone-offset tint tinymce tinymce-4 tinymce-5 tinymce-plugins tippyjs tiptap title tkinter toast toast-ui-image-editor toastr toggle togglebutton toggleswitch token tomcat tomcat9 tone.js toolbars tooltip top-level-await tornado tostring touch touch-event touchableopacity touchmove traffic trail trailing-whitespace transactions transform transition transitions translate translation transloco transparency transparent transpiler transpose travis-ci tree tree-shaking tree-traversal treemap treesitter treetableview treeview tri-state-logic triangle triggers trim trpc.io truetype truncate truncation try-catch ts-check ts-jest ts-loader ts-node ts-node-dev tsc tsconfig tsconfig-paths tsd tslint tsserver tsx tsyringe tumblr tumblr-html tumblr-themes tuples turborepo twa tween twig twilio twilio-api twilio-conversations twilio-video twitter twitter-bootstrap twitter-bootstrap-2 twitter-bootstrap-3 twitter-bootstrap-4 twitter-card two-way-binding txt type-alias type-assertion type-conversion type-declaration type-definition type-erasure type-hinting type-inference type-level-computation type-narrowing type-only-import-export type-parameter type-safety typeahead typeahead.js typechecking typedjs typeerror typeface.js typeform typegoose typegraphql typeguards typemoq typeof typeorm types typescript typescript-5 typescript-class typescript-compiler-api typescript-conditional-types typescript-declarations typescript-decorator typescript-eslint typescript-eslintparser typescript-generics typescript-mixins typescript-module-resolution typescript-namespace typescript-never typescript-types typescript-typings typescript-utility typescript1.5 typescript1.6 typescript1.8 typescript2.0 typescript2.2 typescript2.4 typescript2.9 typescript3.0 typescript4.0 typetraits typing typo3 typo3-10.x typography typoscript ubuntu ubuntu-16.04 ubuntu-20.04 udp uglifyjs ui-automation ui-calendar ui-grid ui-scroll ui-select ui-testing ui-toolkit ui.bootstrap uiactionsheet uialertcontroller uibinder uicomponents uikit uint uint8array uiscrollview uiswitch uiview uiwebview ultrawingrid umd uncaught-exception undefined underline underscore.js undertow unexpected-token unhandled-promise-rejection unicode unicode-string unified.js union union-types unique-values unit-testing units-of-measurement unity-game-engine universal unlink unsafe-inline unsubscribe unused-variables updates upgrade upload uploader uppercase uri uri.js url url-parameters url-parsing url-redirection url-rewriting url-routing url-scheme urllib2 urlsearchparams urql usability use-case use-context use-effect use-reducer use-ref use-state usefaketimers user-agent user-controls user-event user-experience user-input user-interface user-permissions user-roles userchrome.css userscripts utc utf utf-8 uuid uwp uwsgi v-autocomplete v-data-table v-for v-slider v-slot vaadin vaadin-flow vaadin14 vagrant validation validationerror valuechangelistener vanilla-extract var variable-assignment variable-fonts variable-length variables variadic-functions variadic-tuple-types variance vb.net vba vbscript vector-graphics vega vega-embed vega-lite velo vendor-prefix vercel version version-control versioning vertical-alignment vertical-scrolling vetur video video-codecs video-processing video-streaming video.js videogular videogular2 view view-transitions-api viewchild viewport viewport-units vim vimeo vimium virtual-dom virtualscroll virus vis.js vis.js-network visibility visible visual-studio visual-studio-2010 visual-studio-2012 visual-studio-2013 visual-studio-2015 visual-studio-2017 visual-studio-2019 visual-studio-2022 visual-studio-code visual-studio-cordova visual-studio-monaco visual-testing visual-web-developer vite vitepress vitest vlc vmware vmware-clarity voiceover void vpc vs-web-site-project vscode-debugger vscode-extensions vscode-jsconfig vscode-settings vsto vue-class-components vue-cli vue-cli-3 vue-component vue-composition-api vue-data vue-i18n vue-mixin vue-property-decorator vue-props vue-router vue-router4 vue-script-setup vue-test-utils vue-transitions vue-typescript vue.js vuejs-transition vuejs2 vuejs3 vuejs3-composition-api vuelidate vuepress vuetify.js vuetifyjs3 vueuse vuex vuex4 w3.css w3c w3c-validation wai-aria wait walkthrough wallet-connect war warnings was watch watch-face-api wav waveform wcag wcag2.0 wcag2.1 wcf wear-os weasyprint weather-api web web-accessibility web-applications web-audio-api web-chat web-component web-config web-crawler web-deployment web-deployment-project web-development-server web-frameworks web-frontend web-hosting web-inspector web-notifications web-parts web-performance web-scraping web-scraping-language web-services web-site-project web-sql web-standards web-storage web-technologies web-vitals web-worker web.xml web3 web3js webapi webapi2 webassembly webauthn webbrowser-control webcam webclient webcodecs webdatarocks webdeploy-3.5 webdriver webflow webfonts webforms webgl webgpu webhooks webintents webix webkit webkit-animation weblogic webmethod webp webpack webpack-2 webpack-4 webpack-5 webpack-bundle-analyzer webpack-config webpack-dev-server webpack-file-loader webpack-hmr webpack-html-loader webpack-module-federation webpack-style-loader webpage-screenshot webrtc websecurity webserver websocket webspeech-api webstorm webusb webview webview2 webvtt weebly week-number wget wgsl whatsapp while-loop white-labelling whitelist whitespace widget width wildwebdeveloper window window-resize window.location windows windows-10 windows-7 windows-8.1 windows-authentication windows-server-2008 windows-subsystem-for-linux winforms winston winui-3 wireless wix wkhtmltopdf wkwebview wkwebviewconfiguration woff woff2 wonderpush woocommerce woocommerce-theming woothemes word-break word-cloud word-count word-spacing word-wrap wordpress wordpress-gutenberg wordpress-rest-api wordpress-theming worker worker-loader workflow workspace wow.js wpbakery wpf wrapper ws wsh wsl-2 wso2 wso2-identity-server wso2-micro-integrator wtforms wysiwyg x-editable x-xsrf-token xaml xampp xaringan xcode xcode12 xcodebuild xhtml xhtml-1.0-strict xhtml-1.1 xhtml2pdf xliff xlsx xml xml-namespaces xml-parsing xml.etree xmlhttprequest xng-breadcrumb xor xpath xslt xss xstate xtermjs yahoo-mail yaml yarn-v2 yarn-workspaces yarnpkg yarnpkg-v2 yaxis yeoman yeoman-generator yeoman-generator-angular yii2 yii2-advanced-app youtube youtube-api youtube-data-api youtube-iframe-api ytdl yui yup z-index zend-form zend-framework zend-framework2 zendesk zigzag zingchart zip zipalign zipkin zod zoho zone zone.js zonejs zooming zsh zurb-foundation zustand

Copyright © angularfix