Communication between parent and child windows in Angular
Its a common scenario to open a new child window to get some information from the user and the pass the data to the parent window.
I am sharing a simple example of opening a component in a new window and pass the user input back to the parent window to process it further.
Consider a HomeComponent with a button to open a child login window. This window will display a LoginComponent.
Routing:
const routes: Routes = [{
path:'',
redirectTo:'/home',
pathMatch:'full'
},
{
path:'home',
component:HomeComponent,
},
{
path:’login’,
component:WindowComponent
}
]
Template:
<button (click)=”openLoginWindow()”>Login</button>
Class:
export class HomeComponent implements OnInit {windowRef=null;openLoginWindow(){this.windowRef= window.open(“/login”,”child”, “toolbar=no,location=no,directories=no,status=no,menubar=no,titlebar=no,fullscreen=no,scrollbars=1,resizable=no,width=430,height=220,left=500,top=100”);this.windowRef.addEventListener(“message”,this.receivemessage.bind(this), false);
}receivemessage(evt:any){
console.log(evt.data)
}}
When I click on the button, we are opening a window, whose url “/login” matches the WindowComponent path. The reference of this child window is stored in windowRef.
When the WindowComponent sends back data, a message event is triggered which is handled by a method receivemessage() to print the received data.
this.windowRef.addEventListener(“message”,this.receivemessage.bind(this), false);
Now lets see how the WindowComponent sends back the data to HomeComponent.
WindowComponent is just a simple login form.
<form [formGroup]=”authForm” (ngSubmit)=”login(authForm)”>
<label>Username:</label>
<input type=”text” formControlName=”username”>
<br>
<label>Password:</label>
<input type=”password” formControlName=”password”>
<br>
<button type=”submit”>Login</button>
</form>
Class:
export class WindowComponent implements OnInit {
constructor() { }
authForm:any;ngOnInit(): void {
this.authForm=new FormGroup({
username:new FormControl(“”,[Validators.required]),
password:new FormControl(“”,[Validators.required])
})
}login(f){
parent.postMessage(f.value,location.origin);
window.close();
}}
Once we fill out the username and password and click on the login button, we are sending the form data to the parent window.
parent.postMessage(f.value,location.origin);
parent is equivalent to saying window.parent. We are referring to the parent window which will receive the message i.e form data.
The first argument of the postMessage() is the message I want to send.
postMessage() is very useful for cross origin communication between window objects. But in our example, the source and destination origin is the same.
So the second argument which should be the url of the destination window will be location.origin.
location.origin will return the current window url and port number.
The parent window recevies the data via message event which is handled in the receivemessage() method.
Finally we are closing the child window via window.close().
This is a very simple example. But there are many other checks you could perform. For instance, you could check if the parent window is refreshed and perform some action(eg: closing the child window)based on it using the below piece of code.
window.opener.addEventListener(‘unload’,handler, false);
handler is a function that will perform the action when the parent window is refreshed.
Please let me know your comments:)