0

Note : please ignore syntax error for this post.
My project setup is as follow.

boot.ts <= ParentComponet, has <routerOutlet> & sub components, contains navigation for sub coponents.
-----Home.ts <= default view using useAsDefault
-----login.ts <= but by overriding routerOutlet, I check whether user is authenticated or not. If not (here obviously), load login component.


models.ts

export class UserModel()
{
    private userName:string;
    private isLoggedIn:boolean;
}

authService.ts

import {UserModel} '.../models.ts'
...
...
public let um=new UserModel();  // I don't know how to go ahead from here.
constructor()
{
  um.userName="Guest";
  um.loggedIn=true;  // lets not deal with it for now.
}

setUserDetail(username:string)
{  

   um.userName=username;
   um.loggedIn=true;


   Please note here that when it changes um model, I want to update boot.html view
}

getUserDetail:UserModel()
{
  return um;
}

authentication(username:string,password:string)
{   
        ...// I have http server call here. but not shown.
        ... //database query
        um.userName= "field from DB";
        um.loggedIn=true;
        ...//return observable
 }

login.ts ...

login(username,password)
{
  auth.authentication(username,password)
  .subscribe(() => {
     auth.setUserDetail(username);  // this should update boot.html view immediately.
  });
}

boot.ts

import {UserModel} '.../models.ts';
import {authService} '.../authService.ts';

constructor(auth:authService)
{
    console.log(auth.getUserDetail());  //log is correct. no problem till here.

   // Note: When we run the app, it may get UserModel object and display to VIEW. But after login how can I update boot.html view?

    1) how to bind upcoming object value to view?
    2) when page is refreshed same object should be returned.         
}

boot.html

...
<li ngIf="{{um.loggedIn}}">{{um.userName}}</li>
...

Do I need to use EventEmitter?

http://plnkr.co/edit/uPb0eHXPke41zSa9IBdS?p=preview
This shows how to update two views using shared service.

if anyone is interested to know about overriding routerOutlet
Angular 2 Authentication with child routes

Community
  • 1
  • 1
micronyks
  • 54,797
  • 15
  • 112
  • 146

1 Answers1

0

I find the code of your login method a bit strange. I would use this instead to define the callback provided to the subscribe method:

login(username,password)
{
  auth.authentication(username,password)
  .subscribe(() => {
     auth.setUserDetail(username);  // this should update boot.html view immediately.
  });
}

Edit

You could use an EventEmitter property into your service. For more details, see this link:

Community
  • 1
  • 1
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • I have written the same. But having syntax error as post is very long. I have not shown everything here. I'm having `http.post` call to the server in `authentication method` of `authService`. – micronyks Feb 18 '16 at 13:32
  • how `setUserDetail` from `authService` would change `boot.html` ? and how to bind object with property to boot.html? – micronyks Feb 18 '16 at 13:35
  • Okay no worries! I try your plunkr but it seems to work... When I click on the "Change the name" button, both navbar and content area are updated... Do you have the same behavior? – Thierry Templier Feb 18 '16 at 13:45
  • Oh @theirry. I was away so could answer you. Immediately. Yup plunkr is working fine. It has been given for the reference purpose. Let me make it simple. If u run the app, how to bind `object with two properties`, say `guest & true`? With that login screen is there. User gets logged in, and store his info at authService and as user gets redirected to Home, same object's two properties should be updated and so view... I hope it makes it clear now. – micronyks Feb 18 '16 at 16:08
  • 1) When you run d app, `boot.ts` calls getUserDetail fun which reurns an object. How to bind that object to boot.html view ? 2) user gets logged in, store his info at authService , but this happens through `login.ts` component so how to update boot.html? – micronyks Feb 18 '16 at 16:25
  • I would say: if you share the instance and it's not a primitive type just reference the field. If it's primitive type, you can lose the reference because it's overriden. More generally I would use an EventEmitter into your service for this. I updated my answer and give you the link to a question for such use case... – Thierry Templier Feb 18 '16 at 18:19
  • It help me but not yet satisfied. Look at my new question. You might help me. – micronyks Feb 19 '16 at 08:48