Thursday 24 November 2022

angular v15 directive ngFor handling empty list

 


// hello.component.ts


import { Component, Input } from '@angular/core';
import { NgForEmpty } from './ng-of-empty';

@Component({
selector: 'hello',
template: `<h1>Hello {{name}}!</h1>
<ul>
<li *ngFor="let p of persons; empty: emptyTmpl">{{p}}</li>
</ul>
<ng-template #emptyTmpl>Empty list</ng-template>
`,
styles: [`h1 { font-family: Lato; }`],
standalone: true,
imports: [NgForEmpty],
})
export class HelloComponent {
@Input() name: string;
persons = ['Dignāga','Dharmakīrti','Kamalaśīla','Śāntarakṣita',
             'Asanga','Vasubandhu'];
}


// ng-of-empty.ts



import { NgFor, NgIf } from '@angular/common';
import { Directive, inject, Input } from '@angular/core';

@Directive({
selector: '[ngFor]',
standalone: true,
hostDirectives: [
{ directive: NgFor, inputs: ['ngForOf'] },
{ directive: NgIf, inputs: ['ngIfElse: ngForEmpty'] },
],
})
export class NgForEmpty<T> {
private readonly ngIf = inject(NgIf, { host: true });

@Input() set ngForOf(ngFor: T[] | undefined) {
this.ngIf.ngIf = ngFor && ngFor.length > 0;
}
}




Sunday 20 November 2022

Angular functional guard to check on the user role to guard your routes

functional guard to check on the user role  to guard your routes. 


The functional guard accepts a param for the user role 


Less verbose than a class based guard



    use canMatch to skip a route dynamically in combination with functional guards. 

  👍 Super handy when a path should lead to different comp depending on some logic 

  👋 canLoad is going to be deprecated in favor of canMatch


    


Saturday 19 November 2022

Directive composition API in Angular 15

our directive stand alone by adding standalone property inside directive declaration 

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

@Directive({
  selector: '[appRedColor]',
  host:{'style': 'color:red;'},
  standalone: true
})
export class RedColorDirective {

  constructor() { }

}

Now the text inside testdirective component will be displayed in red color.

<app-testdirective></app-testdirective>

And our code looks simple without adding an extra directive in component tag.

We can add more than one directive inside hostDirectives property.


@Component({
  selector: 'app-testdirective',
  templateUrl: './testdirective.component.html',
  styleUrls: ['./testdirective.component.scss'],
  hostDirectives:[RedColorDirective,HeightDirective,FontStyleDirective,......]
})
export class TestdirectiveComponent {
}

We can add hostDirectives inside an another directive as well.

Saturday 15 October 2022

Reusable ng-template with parameters




<ng-template #loading let-overlayHeight="overlayHeight"
let-loaderLeft="loaderLeft" let-marginTop="marginTop">
<div class="overlay" [style.marginTop]="marginTop || ''"
[style.height]="overlayHeight || '100%'" style="position:relative;">
<div class="loader" [style.left]="loaderLeft || '40%'"
        style="position:relative;top:35%">
<svg viewBox="0 0 86 80">
<polygon points="43 8 79 72 7 72"></polygon>
</svg>
</div>
</div>
</ng-template>


Use

<ng-template *ngIf="paretoProductCategoriesChartLoading"
[ngTemplateOutlet]="loading"
[ngTemplateOutletContext]="{overlayHeight: '280px',marginTop:'20px'}">
</ng-template>

Create a common Html element within angular template.

Sunday 17 July 2022

change label css when checkbox checked

 

<form>
<label>
<input type="checkbox">
Make this red when checked
</label>
</form>
<button>Make this red too!</button>

<style>
body:has([type="checkbox"]:checked) label,
body:has([type="checkbox"]:checked) button {
color: red;
}
</style>


change label css when checkbox checked

Saturday 18 June 2022

ng-container with ngTemplateOutlet and ng-template with context variable

<div *ngIf="!multiOptionsChart.length" class="row">
<ng-container *ngTemplateOutlet="
chartBlock;
context: {
optionItem : options,
chartType:'single'
}">
</ng-container>
</div>

<div *ngIf="multiOptionsChart.length" class="row">
<div *ngFor="let optionItem of multiOptionsChart; let i = index">
<ng-container *ngTemplateOutlet="
chartBlock;
context: {
optionItem : optionItem ,
chartType:'multi'
}">
</ng-container>
</div>
</div>

<ng-template #chartBlock
let-optionItem="optionItem"
let-chartType="chartType">

<div class="graph-action">
your multi and single chart type common code
</div>

<ng-container *ngIf="chartType === 'multi'">
<span>chartType</span>
<span>: {{ chartType }}</span>
</ng-container>
<ng-container *ngIf="chartType === 'single'">
<span>single chartType</span>
<span>: {{ chartType }}</span>
</ng-container>
Name : {{ optionItem.name }}
</ng-template>


Monday 13 June 2022

Debug websites in different browsers and devices and write their css media queries

 

 

        css media query for all devices

        https://simplecss.eu/


You can also test in diffrent device using this tool 

Download from    https://www.lambdatest.com/

    


   in Ubuntu  

    step 1 :     chmod a+x LTBrowser.AppImage

    step 2 for run :   ./LTBrowser.AppImage 
 

       

Example 13" Macbook Pro Retina
@media only screen and (max-width : 1600px) and (max-height : 2560px) {
}



Thursday 2 June 2022

Vue Dynamic Directive Arguments and vue event binding

   Vue Dynamic Directive Arguments



  Vue Promise

  



 If you do not want the root element of a component to inherit attributes, you can set 

  inheritAttrs: false

in the component’s options



vue event shortcut

  


Tuesday 31 May 2022

use memo in your angular component template function call

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

function hasDifferentArgs(prev: unknown[], next: unknown[]) {
if (prev.length !== next.length) return true;
for (let i = 0; i < prev.length; i++) {
if (!Object.is(prev[i], next[i])) return true;
}
return false;
}

function memo(fnToMemoize) {
let prevArgs = [{}];
let result;

return function (...newArgs) {
if (hasDifferentArgs(prevArgs, newArgs)) {
result = fnToMemoize(...newArgs);
prevArgs = newArgs;
}
return result;
};
}

function expensiveComputing(name: string) {
return '$' + name + '$';
}

@Component({
selector: 'my-app',
template: 'Hello, {{fancyName(name)}}!',
})
export class AppComponent {
name = 'World';

fancyName = memo((name) => expensiveComputing(name));
}


Monday 23 May 2022

how to disable anydesk autostart in ubuntu

 I've found the following approach to disable the AnyDesk service. In this way, you can run it manually.


systemctl disable anydesk.service

You can also check its service status:


systemctl status anydesk

nb: you might want to stop it first (or after) if it is running:


  service anydesk stop

Thursday 28 April 2022

MongoDB locally on Ubuntu 20.04 code=exited, status=14

 


$ sudo chown mongodb:mongodb /tmp/mongodb-27017.sock $ sudo systemctl status mongod $ sudo systemctl start mongodb Failed to start mongodb.service: Unit mongodb.service is masked. $ sudo systemctl unmask mongodb Removed /etc/systemd/system/mongodb.service. $ sudo systemctl start mongodb Job for mongodb.service failed because the control process exited with error code. See "systemctl status mongodb.service" and "journalctl -xe" for details.


$ sudo service mongod stop
$ sudo apt-get purge mongodb-org*
$ sudo rm -r /var/log/mongodb
$ sudo rm -r /var/lib/mongodb
$ sudo apt-get install -y mongodb-org

$ sudo systemctl start mongod
$ sudo systemctl status mongod
● mongod.service - MongoDB Database Server
     Loaded: loaded (/lib/systemd/system/mongod.service; enabled; vendor preset: enabled)
     Active: active (running) since

Saturday 9 April 2022

TypeScript Record Type

 Utility Types

A Record is a utility type — that means it is a type especially defined by TypeScript to help with a certain problem.

example you have a data set like this:

const myData = {
"adfsdfsd1" : { firstName: "Pranay", lastName: "Soni" },
"sddsf24" : { firstName: "Pranay1", lastName: "Soni1" },
"sdfsdf5" : { firstName: "Pranay2", lastName: "Soni2" }
}

Our data set has an ID for its key, which is of type string. All of the values have the same format — that is, they have a firstName and lastName.

For this data structure, a Record is the best utility type to use. We can define our data structure type as follows:

type User = {
firstName: string,
lastName: string
}
const myData:Record<string, User> = {
"123w" : { firstName: "Pranay1", lastName: "Soni1" },
"124s" : { firstName: "Pranay2", lastName: "Soni2" },
"125f" : { firstName: "Pranay3", lastName: "Soni3" },
}

A Record takes the form Record<K, T>, where K is the type of the key, and T is the type of the values.

Above, we defined a new type User for our values, and set our keys to type string.

Record Types and Union Types

Sometimes, we can have an object with a predefined set of possible keys. This is particularly true when calling from an API. For example:

const myData = {
"india" : { firstName: "Pranay1", lastName: "Soni1" },
"usa" : { firstName: "Pranay2", lastName: "Soni2" },
"japan" : { firstName: "Pranay3", lastName: "Soni3" },
}

Let’s presume that for our data set above, the key can only be three values: uk, france or india. In this case, we can define a type for User, and a union type for our key:

type User = {
firstName: string,
lastName: string
}
type Country = "uk" | "france" | "india";
const myData:Record<Country, User> = {
"india" : { firstName: "Pranay1", lastName: "Soni1" },
"usa" : { firstName: "Pranay2", lastName: "Soni2" },
"japan" : { firstName: "Pranay3", lastName: "Soni3" },
}

Using this method, we can enforce strict rules about the values the key is allowed to be, along with the type our values should conform to

Saturday 2 April 2022

mongoose full text search in nestjs


import * as mongoose from 'mongoose';
const SALT_ROUNDS = 10;

function transformValue(doc, ret: { [key: string]: any }) {
delete ret._id;
delete ret.password;
}

export interface IUserSchema extends mongoose.Document {
organizationId: string;
email:string,
password:string,
userRole:[],
status:string,
firstName:string,
lastName:string,
address:string,
}


export const UserSchema = new mongoose.Schema<IUserSchema>(
{
organizationId:{
type: String
},
email:{
type: String,
},
password: {
type: String
},
userRole: {
type: []
},
firstName: {
type: String
},
lastName: {
type: String
},
address: {
type: String
},
status: {
type: String
},
},
{
toObject: {
virtuals: true,
versionKey: false,
transform: transformValue,
},
toJSON: {
virtuals: true,
versionKey: false,
transform: transformValue,
},
},
);

UserSchema.index({ "$**": "text" },
{ name: "userTextIndex",locale: 'en', strength: 2}) //


in Your Nest Js Mongo Config Service look like import {
MongooseOptionsFactory,
MongooseModuleOptions,
} from '@nestjs/mongoose';

export class MongoConfigService implements MongooseOptionsFactory {
createMongooseOptions(): MongooseModuleOptions {
return {
uri: process.env.MONGO_DSN,
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
};
}
}

db.getCollection('user').find({ $text: { $search: "activ"} }); mongoose full text search in nestjs
mongodb full text search in nodejs
mongodb full $text $search in nodejs
mongoose create text indexes




Sunday 16 January 2022

create request logger in Node.js AsyncLocalStorage

AsyncLocalStorage is a class which creates an asynchronous state within
callbacks and promise chains. It allows us to persist context through
a lifetime of async operations, for example within a web request,
RabbitMQ event or WebSocket message.

we will make our logger inform us about the path of request and time
delta between the request start and log call.


const express = require("express");

const { AsyncLocalStorage } = require("async_hooks");
const { v4: uuid } = require("uuid");

const indexRouter = require("./routes/index");

const app = express();
const context = new AsyncLocalStorage();

function requestLogger(...args) {
const store = context.getStore();
const id = store.get("id");
const timeStart = store.get("timeStart");
const { originalUrl } = store.get("request");
console.log(`${id}, ${originalUrl}, ${+new Date() - timeStart}ms`, args);
}

app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use((req, res, next) => {
const store = new Map();
context.run(store, () => {
store.set("id", uuid());
store.set("timeStart", +new Date());
store.set("request", req);
requestLogger("request started");
next();
});
});

app.use("/", indexRouter);

app.use((req, res, next) => {
requestLogger("request ended");
next();
});

module.exports = app;

 

BehaviorSubject and ReplaySubject in Rxjs

 

  • BehaviorSubject

A variant of Subject that requires an initial value and emits its current value whenever it is subscribed to.

  • ReplaySubject

A variant of Subject that “replays” or emits old values to new subscribers. It buffers a set number of values and will emit those values immediately to any new subscribers in addition to emitting new values to existing subscribers.