Tuesday, 15 February 2022

Angular 10 + API service call key notes

 


Things to Angular Service calls:


1. Do we need state management or not . if we need then the API calls goes with effects concept.

2. Consider HTTP interceptors. Are we using any JWT to pass Bearer <Token> on every request.

3. Advanced is to create the model(interface or class) for each response and parse them and send to component. Simple is to parse the HTTPresponse and get data from body. 


4. Normal way is to make the api call in service ->  fetch the data(Observable)  -> 

pass it to pipe -> do the map() and parse the data -> return to component. 



5.Depends on the data to show: ex: menu1 api=> /api/menu1 


say if it has only htmlText then below is the one. BY default  HTTP error interceptor will parse each response to see the response status is 200 (success) , 401(unauthorized)  , 403(forbidden) , 500(internal server ) and handle them accordingly..


{

'id':1,

'name': 'Yuv'

}



6. if data is array then consider :  


[ {

'id':1,

'name': 'Yuv'

}, {

'id':2,

'name': 'Raj'

}]

Wednesday, 9 February 2022

Angular Routing Mistake . Angular URL loop : Throttling navigation to prevent the browser from hanging. Command line switch –disable-ipc-flooding-protection can be used to bypass the protection

"Throttling navigation to prevent the browser from hanging. Command line switch –disable-ipc-flooding-protection can be used to bypass the protection"


Hi , if you are facing above issue then the Angular navigation stuck in a loop.

Possible root cause is Angular not able to detect the route name or wrong route name is given routing module. 

Consider an example:

 1. You are in login page[/login] and on success you will  redirect to home page[/home]

 2. Consider if no route is found for home then we will redirect to login page [/login] . 

 3. Now if we keep the wrong name or  with slash to the home routing url [path: '/home' or  path: 'home1'] in the routing module then Angular cannot find the path and hence it redirect user to login page. 

 4. But at this point you already authenticated user with login button click and have current user in ur local storage. This will push the router navigation again to home page . 

 5. So, Login to Home --> not able to find Home path because we gave it '/home' or home1  --->   Redirect to Login component --> Login component sees authentication succesful and token is available and hence ---> redirect again to Home  --> not able to find home , so go back to login 


   ABOVE scenario formed a CIRCULAR loop by which we ll receive above message from Angular. 


Kindly rectify your routes and see there is no circular dependencies. 

Monday, 7 February 2022

Angular Providers , providedIn , Injectable Key points

 "Using the @Injectable() providedIn property is preferable to the @NgModule() providers array because with @Injectable() providedIn, optimization tools can perform tree-shaking, which removes services that your application isn't using and results in smaller bundle sizes.Tree-shaking is especially useful for a library because the application which uses the library may not"


"If a module defines both providers and declarations (components, directives, pipes), then loading the module in multiple feature modules would duplicate the registration of the service. This could result in multiple service instances and the service would no longer behave as a singleton."


"If you have a module which has both providers and declarations, you can use this technique to separate them out and you may see this pattern in legacy applications. However, since Angular 6.0, the best practice for providing services is with the @Injectable() providedIn property."

Monday, 31 January 2022

CSS positions: Relative , Sticky, Absolute , Fixed , Static

Hey Guys, 


I spent  little more time to learn  CSS positions and below is an example you can try to understand. 

Try below one : 


    <div class="parent"> 

<p  style = "position:relative;left:10%;border:2px black solid;"> I am relative </p>

<!-- Occupy the position after above image and align towards left by 10 % .  --> 



<p  style = "position:static;left:10%;border:2px yellow solid;">  I am Static </p>

  <!-- Does not affect any change in left property . its static and align to its normal position --> . 



<p  style = "position:fixed; left:10%;bottom:0%;border:2px blue solid;">  I am fixed </p> 

 <!-- It takes document as its parent and align item based on document level.  Does not change even when u scroll --> . 


<p  style = "position:absolute; left:30%; top : 50%;border:2px red solid;">  I am absolute </p> 

 <!-- Takes the container as its parent. Nearest ancestor and act like fixed. --> . 


<p  style = "position:sticky; left:10%; top:0%; border:2px green solid;">  I am sticky </p> 

 <!-- A sticky element toggles between relative and fixed, depending on the scroll position. It is positioned relative until a given offset position is met in the viewport - then it "sticks" in place (like position:fixed). --> . 


 <p> FILL IN HERE WITH SOME EXTRA DATA TO SEE STICKY effect . Sticky Effect works if you have scrollable data. </p>

    </div>

Wednesday, 22 December 2021

PHP + LARAVEL + Xdebug + VSCODE + DEBUGGER + mac OS


 Hey there, 

i have recently tried running the debugger in VSCODE for my LARAVEL project.

Step 1: PHP 

  •  I have installed PHP via home brew. 

                 brew install php@7.4 

  • If you want you to unlink your existing PHP and link new the version we have installed then run this. ex: You have had 7.3 with your system and we have installed 7.4 . So, to use 7.4

                     brew unlink php@7.3

            brew link php@7.4

  • Now, if u run php -v on terminal . you will see php 7.4 version.   


Step  2: XDEBUG

    • Ensure we have xdebug installed if not then kindly install it from xdebug for mac OS
      • once installation is successful then u can see xdebug on php -v command output


Step 3: Install  PHP debug in VSCODE from here PHP DEBUG

Step 4: Enabling XDEBUG debug mode and step debugging. 

    • Go to your php ini file and add below config. You can find the ini file at below path in mac.  
      • nano /usr/local/etc/php/7.4/php.ini     
      • Paste below in ini file.                                                          [Xdebug]

        zend_extension="xdebug.so"

        xdebug.mode=debug

        xdebug.client_port=9001

        xdebug.log="/tmp/xdebug.log"

        xdebug.client_host="127.0.0.1"

        xdebug.start_with_request=yes    

Step 5: Run & Debug in VSCODE



    •        Go to VSCODE and left side select run & debug option. select PHP configuration and paste below in .vscode/launch.json 

{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9001,
"pathMappings": {"<path to your Laravel codebase>": "${workspaceFolder}"},
"ignore": [
"**/vendor/**/*.php"
]
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 8000
}
]
}


Step 6: Run your laravel project  which runs on port 8000 or your desired port

          php artisan serve 

Step 7:  Things to keep in mind

  • we have kept the port no 9001 for xdebug configuration . Both in VSCODE launch.json and php.ini file. 
  • we have our laravel server running at port no: 8000
  • So xdebug listens on port 9001 and laravel on 8000. whenever u hit localhost:8000 ---> xdebug will listen and start step debugging.

Thursday, 16 December 2021

Angular Testing Observables (making async tests to sync )


RxJS marble testing

 getTestScheduler().flush(); // flush the observables

fakeAsync()

The fakeAsync() function enables a linear coding style by running the test body in a special fakeAsync test zone. The test body appears to be synchronous. There is no nested syntax (like a Promise.then()) to disrupt the flow of control.

     We use tick() to advance the virtual clock of the setTimeout and other observables values and there by making it sync instead of waiting for given time out and waiting on service call to give observable. 

waitForAsync() 

It hides some asynchronous boilerplate by arranging for the tester's code to run in a special async test zone

But the test's asynchronous nature is revealed by the call to fixture.whenStable(), which breaks the linear flow of control.


In short to make the async tests to sync and advance the async queue 

Rxjs marble testing --> getTestScheduler().flush();

fakeAsync() --> tick()

waitForAsync()  -->  fixture.whenStable()


Reference:

https://angular.io/guide/testing-components-scenarios

Wednesday, 17 November 2021

ER_LOCK_WAIT_TIMEOUT issue resolved , dead lock transaction mysql

 Hey guys,

Today, i faced an issue with transaction getting dead locked in mysql. i was unable to perform any action on the locked table. 

I created a transaction with autocommit : false and forgot to either rollbock or commit the transaction.

At the same time another transaction been created and tried to access the same table and final result is 

ER_LOCK_WAIT_TIMEOUT: Lock wait timeout exceeded; try restarting transaction


Solution:
--------------

SHOW PROCESSLIST 

See if your query is present in the processes and kill the <id> which causing the table lock.

KILL <processid>

Above command did not help me as process or query id is not present to overcome the problem. 

Dig in more to check the transactions list and try to kill the one that got dead locked.


First  , let's get some Engine status. i m using INNODB engine for Mysql.


SHOW ENGINE INNODB STATUS

This will result us with below sample output. 

----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 5367
OS WAIT ARRAY INFO: signal count 4706
RW-shared spins 0, rounds 2666, OS waits 728
RW-excl spins 0, rounds 1878, OS waits 44
RW-sx spins 34, rounds 217, OS waits 4
Spin rounds per wait: 2666.00 RW-shared, 1878.00 RW-excl, 6.38 RW-sx
------------
TRANSACTIONS
------------
Trx id counter 418476
Purge done for trx's n:o < 418416 undo n:o < 0 state: running but idle
History list length 0
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 421985361275640, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421985361274720, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
--------


In the list of transactions , if you any lock struct(s) more than 0 then you will get it with query ID and thread id 

ex: MySQL thread id 197, query id 771 localhost

Now we need to kill the thread thats causing the dead lock situation with KILL command. 

KILL 197  


If you want to kill the query then KILL QUERY 771  followed by KILL 197 

Thus, we can overcome to transaction dead lock and Er_lock_wait_time_timeout error. 


if you really want to Dig in more on this then below link will help you :

https://severalnines.com/database-blog/how-fix-lock-wait-timeout-exceeded-error-mysql














Monday, 8 November 2021

MYSQL: ER_WRONG_FIELD_WITH_GROUP: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column

Hey guys,


Recently when we run one of our query with group by . we encountered an MYSQL error as like below:

ER_WRONG_FIELD_WITH_GROUP: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column <column name> which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by




When we dig in deeper, we came to know that we have enabled only_full_group_by  which is by default in MySQL 5.7.5 and later. 


For example. Query


select name , phone_number, count(*)  from contact 

group by phone_number ;



contact table :

----------------------

  name     phone_number


   Raj       123

   Ram     123 

   Karan    456


See above table has 2 names pointing to same number 123 . so when we group by the data with phone_number it tries to count no . of records based on phone_number.


Now when we keep the name in the selection list . MYSQL has to pick only one name to show to user . 

System will confuse which name to pick Raj / Ram . 


so , when we enable only_full_group_by . we are letting mysql to not accept queries with functional independence in the selection list.  if they are functionally dependent or primary key then it will work. 


To overcome above problem :  2 solutions


Solution 1: 


   Disable only_full_group_by . follow below link 


     https://stackoverflow.com/questions/23921117/disable-only-full-group-by



Solution 2:


    ANY_VALUE()  function for non-agggregated columns in the selection list. By using this, system picks any one name out of multiple values. 


     select any_value(name) , phone_number, count(*)  from contact 

group by phone_number ; 




Please don't keep the non-aggregated columns in selection list at any cost. If you think its necessary then follow above steps to overcome your problem 


More on only_full_group_by


https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html





Sunday, 7 November 2021

Angular service Re-initialised / Angular service instantiated many times

 Hey Guys,

Recently i came cross a problem with Angular 2 + service  constructor got called multiple times. 


Generally , Angular services are singleton meaning it will be called / instantiated only once across the app if the scope of injection is root. 


If we want to re-create / call constructor mutliple times then we have to keep the service in the specific module PROVIDERS. When we specify in providers then the service will be re-created for that particular module you specified. 

The issue i faced:

 > we have the service with  root injectable.  it clearly states that the service available across the root. 

@Injectable({
  providedIn: 'root'
})
export class TestService
But we kept the service in Providers for particular module say  TestModule
providers: [
    TestService
  ]
This causing the service to be called many times and all the data inside service is re-freshed. 

so, when u keep the service at injectable root then dont put it in providers until its needed or necessary. 


Sunday, 24 May 2020

Angular Reactive Form Validation with Custom Validators

Hey Guys, 

I worked on Angular Form group and Form controls validation recently.  we can validate the whole form controls at one go with angular cross field validation technique. 

Fundamentals & Reference :

Angular Reactive Forms:
https://angular.io/guide/reactive-forms

Validation  with custom validators for whole form:

https://angular.io/guide/form-validation#cross-field-validation


All we have to do is supply the certain options to new FormGroup() constructor. 

So, today we talk about two such properties of FormGroup 

1) Validators:

   This property is used to pass custom validator function. we create the validation functions as a directive which implements   ValidatorFn interface  of angular . It takes an Angular control object as an argument and returns either null if the form is valid, or ValidationErrors otherwise.

Note: Data cloned from the official angular documentaion . 
    Example : 


Form Group : 

const heroForm = new FormGroup({ 'name': new FormControl(), 'alterEgo': new FormControl(), 'power': new FormControl() });

To add a validator function . give option like below:

const heroForm = new FormGroup({ 'name': new FormControl(), 'alterEgo': new FormControl(), 'power': new FormControl() }, { validators: identityRevealedValidator });
Here identityRevealedValidator is a cross field validator function writte in a separate directive like below

Directive:

export const identityRevealedValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => { const name = control.get('name'); const alterEgo = control.get('alterEgo'); return name && alterEgo && name.value === alterEgo.value ? { 'identityRevealed': true } : null;

};Template goes like this to show errors:


<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego. </div>

Now Lets talk about another property of FormGroup
2) updateOn
 > Reports the update strategy of the AbstractControl (meaning the event on which the control updates itself). Possible values: 'change' | 'blur' | 'submit' Default value: 'change'
> Can be used for formControl / formGroup
submit:
> updates the formGroup values on submit instead each blur / change event
blur:
> on blur , the values get updated for formGroup / formControl based on given context.

change:
> On control change the values get updated.


In our above example, if we want to update formGroup values on submit then
const heroForm = new FormGroup({
'name': new FormControl(), 'alterEgo': new FormControl(), 'power': new FormControl() }, { validators: identityRevealedValidator , updateOn: 'submit' });

// the above will set updateOn:'submit/blur/change' for all controls as they are grouped under one formGroup.







Friday, 24 April 2020

pyodbc -mysql connection in MAC OS [solved]

Hey Guys ,

I would like write this post after my personal exploration of making mysql + pyodbc connection successful in MAC OS.

To kick start with :


  1. I don't have mysql odbc drivers in my system.  so we have to download them.                  
    1.  We need to use unixODBC on the Mac because the default driver manager is not compatible with ODBC drivers for some databases. so we need to do this at first                    brew install unixodbc
    2. Download the mysql odbc connecter from this link https://dev.mysql.com/downloads/connector/odbc/ 
    3. Once we have them installed via dmg pacakge . we have them sit in your system. 
    4. Now we need to register these drivers . so that our system can connect. 
    5. Run the command  odbcinst -j in the terminal . you will see list of variables here which shows the data sources path detail files. 
    6. so, plz edit and save odbcinst.ini and odbci.int with below content.  

[MySQL ODBC 8.0 ANSI Driver]
Driver=/<pathin your system> /mysql-connector-odbc-8.0.19-macos10.15-x86-64bit/lib/libmyodbc8a.so
UsageCount=1


Connecting to DB using the odbc driver:

connection_string = (
    'DRIVER=MySQL ODBC 8.0 ANSI Driver;'    'SERVER=localhost;'    'PORT=3306;'    'DATABASE= dbname;'    'UID=root;'    'PWD=<your pwd>;'    'charset=utf8;')
 pyodbc.connect(connection_string);


sqlalchemy error:


  • suppose if we are using sqlalchemy to connect to db using mysql:pyodbc then it throws the below error 

cursor.execute(statement, parameters) TypeError: The first argument to execute must be a string or unicode query.

Fix for above error :   



supports_unicode_statements = True

https://github.com/sqlalchemy/sqlalchemy/issues/4869  : Removing the __init__ function helped me to get rid of the above error