Thursday 6 April 2023

React- nested API call asyn - await

useEffect(() => {

  const getData = async () => {

      try {

          const { data } = await fetchContext.authAxios.get('/myapi/' + auth.authState.id);

          const customerIdList = data.map(value => value.customerID);

          // this fetches list of all customer details in one go

          const customersDetails = (await fetchContext.authAxios.post('/mySecondApi/', {customerIdList})).data;

          // please make necessary changes to the api call

          const updatedData = data.map(value => {

                 // filtering the particular customer's detail and updating the data from first api call

                 const customerDetails = customersDetails.filter(c => c.customerID === value.customerID)[0];

                  

                  return {

                      ...value, // de-structuring

                      customerID: customerDetails

                      // as you asked customer data should replace the customerID field

                  }

              }

          );

          setData(updatedData); // this data would contain the other details of customer in it's customerID field, along with all other fields returned by your first api call

      } catch (err) {

          console.log(err);

      }

  };

  getData();

}, [fetchContext]); 

CSS - regex

 


css regx proeprty You could use the ^= ('starts with') and $= ('ends with')

attribute selectors. 

[class^="dh-"]{} ---> start with dh

[class$="-bl"]{} ---> end with dl


Wednesday 5 April 2023

Angular 13 - Micro front end architecture with angular element, custom element, web compoentsjs

 Angular Micro front end with angular element, custom element, web compoentsjs

=======================================================================

MicroApp: 

Step:1 ng new MicroApp angular 13.0.0

 

ng add @angular/elements

document-register-element 

npm i @webcomponents/custom-elements --save

@webcomponents/webcomponentsjs 

ng add ngx-build-plus polyfill.js 


import'document-register-element' 

import"@webcomponents/custom-elements/src/native-shim";

import "@webcomponents/custom-elements/custom-elements.min"; 


app.module.ts


complete the All the

development of Child/Micro app as entire app or particular component as ???

Particular module??? Note: For Module will be part of any component. So, The

idea will module will become component as mciroApp 

Step:2 MicroApp:> ng add @angular/elements will generate / Impact package.json -> 

"@angular/elements" 

"document-register-element": "1.8.1", --> manull add at devDependency

then do npm install polyfill.ts ->Automatically Import this packages into

polyfills.ts file: if not do it maually import 'document-register-element';


Step:3 Install some polyfills:

 MicroApp:> npm i @webcomponents/custom-elements--save add at pakcage.json 

 "@webcomponents/webcomponentsjs ": "^2.6.0", then npm install Import those packages into polyfills.ts file: import

"@webcomponents/custom-elements/src/native-shim"; 

import "@webcomponents/custom-elements/custom-elements.min"; 

Step:4 MicroApp:> ng add ngx-build-plus will generate / Impact package.json -> "ngx-build-plus":

"^9.0.6", "architect": { "build": { "builder": "ngx-build-plus:browser ....


$while building$ "builder": 

"ngx-build-plus:build", .... 

"budget": [ // to avoid

budget Error Delete this part in Micro UI angular.json , ->budget error occurs 

{

"type": "anyComponentStyle", 

"maximumWarning": "10mb", //from 6kb

"maximumError": "10mb" // from10kb } ] 

"serve": { "builder":"@angular-devkit/build-angular:dev-server", ... 

"test": { "builder":"@angular-devkit/build-angular:karma", 

Step:5 MicroApp:> 

app.module.ts import {BrowserModule } from '@angular/platform-browser';

 import { NgModule,Injector,CUSTOM_ELEMENTS_SCHEMA} from '@angular/core';

 import {createCustomElement } from '@angular/elements';

 bootstrap: [], //webcompionentjs will handle it. while develop it will get filled with appComponent , but in build time it must be empty schemas:

[CUSTOM_ELEMENTS_SCHEMA] // entire app as microUI 


export class AppModule { const

elm = createCustomElement(AppComponent, {injector: this.injector});

console.log('cream-index-ui custom element:::',

customElements.get('cream-index-ui')); 

if (!customElements.get('micro-app1')) {

customElements.define('micro-app1', elm); } 

}


 Step:6 build the child app and

generate dist for master/parent app MicroApp:>ng build --configuration production --output-hashing none --single-bundle true --bundle-styles false --keep-styles false 


Notes: --output-hashing none ->will avoid hashing the file

names. --single-bundle true ->will bundle all the compiled files into a single

JS file. --bundle-styles false ->if we follow the same library css for all theprojects 


Step:6.1 Sometimes budget error will occur. so, Make the correction at

MicroApp angular.json "budgets": [ { "type": "initial", "maximumWarning": "2mb",

"maximumError": "5mb" }, { "type": "anyComponentStyle", "maximumWarning": "2mb",

//from 6kb "maximumError": "5mb" // from10kb } ] copy the dist folder into

master app src/app/assets/MicroApp --> which contains Main.js, index.html,3

other files 


Step:6.2 To do the auto copy -> npm install copyfiles -g // in the

machine/ laptop MciroApp:> npm run copfiles : copyfiles ./dist/*.*

MasterAppPath/src/app/assets ALternatively : ng build make output path from MciroApp 


Step:7 To generate mutliple micro app follow the step -> Step 1- 6

Another child app or MciroApp dist Step:8 MasterApp / ContainerApp / ng new

MasterApp Step: 9 ( Repeat Step 2 ) MasterApp:> will generate / Impact

package.json -> "document-register-element": "1.8.1", --> change the version

1.8.1 if not then npm install 


Step:10 MasterApp app.module.ts import { NgModule,

CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; bootstrap: [AppComponent],

schemas: [CUSTOM_ELEMENTS_SCHEMA] // which allows custom element as recognized

element in master App }) 

export class AppModule { } 

Step:11 MastetApp: Whichever the component need to import/use the in that component MasterApp -Requried


component.component.ts 

childAppPath ='http://localhost:4200/assets/MicroApp/main.js'; 

constructor(){ } 

ngOnInit() {

this.loadScript(this.childAppPath);

 }

 loadScript(scriptPath): void { 

 var alreadyLoaded = false; for (var scriptIndex in document.scripts) { //

console.log(scriptPath, scriptIndex, document.scripts[scriptIndex].src) 

if(!alreadyLoaded && scriptPath === document.scripts[scriptIndex].src) {

alreadyLoaded = true; break; }


 } 

 if (!alreadyLoaded) { 

 const content =document.getElementById('content'); 

 const script =document.createElement('script'); 

 script.src = scriptPath;

content.appendChild(script); } 


or load style and script seperatly


loadStyles(stylePath: string): void { 

var alreadyLoaded = false; 

for (var indexin document.styleSheets) { 

if (!alreadyLoaded && stylePath ===document.styleSheets[index].href)

 { alreadyLoaded = true; break; } 

 if(!alreadyLoaded) {

 var head = document.head; 

 var style =document.createElement("link");

 style.type = "text/css"; 

 style.rel ="stylesheet"; head.appendChild(style);

 } 

 } 

 } 

 loadScript(scriptPath: string,tagName: string): void {

 var alreadyLoaded = false; 

 for (var scriptIndex in document.scripts) { 

 if (!alreadyLoaded && scriptPath === document.scripts[scriptIndex].src) {

 alreadyLoaded = true; break; 

 } 

 } if(!alreadyLoaded) { 

 const content = document.getElementById('content');

 const script = document.createElement('script'); 

 script.src = scriptPath;

content.appendChild(script); 

}


Step:12 MasterApp -


<div id="content"><micro-app1></micro-app1></div>

//

<micro-app1>

  is the custom Tag element mentioned at MicroApp app.module.ts MasterApp:> ng

  serve ==> http://localhost:4200 default if chagne the default port Change the

  ChilAppPath/port

</micro-app1>