I'm struggling around with the observe service approach between two components. I have a profile component that includes a settings component. Both uses the user.service where the provider is defined within app.module.ts. The provider isn't defined any where else. So when I change as example the firstName over the settings.component and save it. The change won't get reflected within the profile.component sidebar until I reload the page.
After hours: I found a solution to do that over an eventemitter that will be trigger as soon as the update occurs. This would solve my problem above but I think this isn't the right way to go since I read the article below:
What is the proper use of an EventEmitter?
Shouldn't it work without an event emmiter?
So my question: What approach would you use for that situation or what is the best practise? Of course there can be an issue within my code. I'm really new in angular.
app.module.ts
Within the app.module.ts i defined:
providers: [UserService]
profile.component.ts
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: any;
Role = Role;
constructor(private _userService: UserService, ) { }
ngOnInit() {
const token = localStorage.getItem('token');
const role = jwt.decode(token).user.role;
this._userService.getUser().subscribe(v => { this.user = v; });
// Event Emmiter Subscription
this._userService.change.subscribe(v => { this.user = v; });
}
}
profile.component.html
<div *ngIf="user" class="container mt50">
<div class="row profile">
<div class="col-md-3">
<div class="profile-sidebar">
<!-- SIDEBAR USERPIC -->
<div class="profile-userpic">
<img gravatar [email]="user.email" [size]="256" class="img-responsive animated bounceIn" alt="">
</div>
<!-- END SIDEBAR USERPIC -->
<!-- SIDEBAR USER TITLE -->
<div class="profile-usertitle">
<div class="profile-usertitle-name">
{{ user.firstName }} {{ user.lastName }}
</div>
<div class="profile-usertitle-job">
{{ user.email }}
</div>
</div>
</div>
</div>
<div class="col-md-9">
<app-profile-settings-admin *ngIf="user.role === Role.ADMINISTRATOR"></app-profile-settings-admin>
</div>
</div>
</div>
user.service.ts
@Injectable()
export class UserService {
public user: any;
constructor(private http: Http) { }
// EVENT EMIITER
public change: EventEmitter<any> = new EventEmitter();
getUser() {
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.get('api/user' + token)
.map((response: Response) => {
this.user = response.json().obj;
return this.user;
})
.catch((error: Response) => Observable.throw(error.json()));
}
updateUser(user) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
const token = localStorage.getItem('token')
? '?token=' + localStorage.getItem('token')
: '';
return this.http.patch('api/user/' + token, body, {headers: headers})
.map((response: Response) => {
const result = response.json();
this.user = result.obj;
// EMIT EVENT
this.change.emit(this.user);
return this.user;
})
.catch((error: Response) => Observable.throw(error.json()));
}
}
profile.settings.admin.component.ts
Within that component there is nothing more than a form that will fire the following code on submit:
onSubmit() {
this._userService.updateUser(this.userForm.value)
.subscribe(
data => {
this._toastyService.default('Settings saved!');
console.log(data);
},
error =>{
this._toastyService.default('Error occured!');
console.log(error);
}
);
}