#routerLink does not render the page
41 messages · Page 1 of 1 (latest)
My first guess is that you didn't import RouterModule
g!codeblock @rare hare But without an error message nor code, all I can do is guess. Post that for better help
@rare hare, you can use the following snippet to have your code formatted and colored by Discord. Replace ts with the language you need (i.e. html, js, css, etc)
```ts
// your code goes here
```
It's imported and the page is being called. Data is being passed. What happens is that my data is not loading in my inputs. It only loads when I refresh the page
code
My 2nd guess is that you are using a snapshot instead of observing on the route params
when I call my page html <button mat-menu-item type="button" routerLink="profile"> <mat-icon>person_pin</mat-icon> <span>Meu Perfil</span> </button>
my profile 👇🏿
I checked on Google browser Network that when I call the page nothing loads but when I refresh the page everything loads correctly
Want to see my route code? I'm loading correctly
interface ViewModel {
requirePassword: boolean;
user?: IUser;
}
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: [ './profile.component.css' ],
})
export class ProfileComponent extends Toolbar implements OnInit {
public readonly vm$: Observable<ViewModel>;
//Fomrulário
public readonly form: FormGroup;
constructor(
private readonly authService: AuthService,
private readonly title: Title,
) {
super(); // This is really not a good idea IMPO.
this.form = new FormGroup({
id: new FormControl(''),
name: new FormControl('', [ Validators.required, Validators.maxLength(255) ]),
email: new FormControl('', [ Validators.required, Validators.maxLength(255), Validators.email ]),
});
this.vm$ = this.authService.getLoggedUser().pipe(
tap((user?: IUser): void => {
if (user) {
this.form.reset(user);
}
}),
map((user?: IUser): ViewModel => ({
requirePassword: Boolean(user),
user,
})),
);
}
ngOnInit(): void {
this.title.setTitle('Dativos | Meu Perfil');
this.breadcrumbs = [ 'Meu Perfil' ];
}
public onSubmit() {
console.log(this.form.value);
}
}
What did you do? Could you explain me?
<app-toolbar [breadcrumbs]="breadcrumbs" [buttons]="buttons" (clickButtonEvent)="clickToolbar($event)"></app-toolbar>
<form *ngIf="vm$ | async as vm; else loading" [formGroup]="form" (ngSubmit)="onSubmit()">
<input type="hidden" formControlName="id">
<mat-sidenav-container hasBackdrop="true">
<div class="component-content">
<mat-card>
<mat-card-title><strong>Meu Perfil</strong></mat-card-title>
<mat-card-content>
<mat-form-field appearance="legacy">
<mat-label>E-Mail</mat-label>
<input matInput placeholder="[email protected]" formControlName="email" autocomplete="off" max="255" required>
<mat-icon matSuffix>mail_outline</mat-icon>
</mat-form-field>
<mat-form-field appearance="legacy">
<mat-label>Nome</mat-label>
<input matInput placeholder="Joaquim José da Silva Xavier" formControlName="name" autocomplete="off" max="255" required>
<mat-icon matSuffix>person_outline</mat-icon>
</mat-form-field>
<div>
<app-input-pass [subForm]="form" [require]="vm.requirePassword"></app-input-pass>
</div>
<mat-divider></mat-divider>
<mat-card-actions>
<button class="button-block" type="submit" mat-flat-button color="primary">Atualizar</button>
</mat-card-actions>
</mat-card-content>
</mat-card>
</div>
</mat-sidenav-container>
</form>
<ng-template #loading><div>Loading...</div></ng-template>
this is good: user$: Observable<IUser>;
No. This is not an @Input, and you already have an observer of user. Don't do this: @Input('user') user?: IUser;
Don't .subscribe to get values out of an Observable. Use the AsyncPipe.
/**
* Carrega os dados do usuário
*/
private loadMyUser() {
this.user$.subscribe({
next: user => {
if (user.abilities) {
this.user = user;
console.log(this.user);
}
}
});
}
So I put all of the data you need for the view, into a Model for the View: a ViewModel
Initializing the form's values from an Observable can be tricky. It is a side effect (https://en.wikipedia.org/wiki/Side_effect_(computer_science)) so in RxJS you use tap (https://rxjs.dev/api/operators/tap) to perform side effects like initializing the Form.
In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, which is to say if it has any observable effect other than its primary effect of returning a value to the invoker of the operation. Example side effects include modifying a non-local v...
When should I use Async Pipe and .subscribe? I always find .subscribe easier
Then I added *ngIf="vm$ | async as vm" to your <form> so you could get the values out of the Observable.
I guess broken code is easier to write 😛
You should always use | async to get values out of an Observable in Angular.
All the things you do to an Observable's emissions (the values that come from/out of an Observable) should be inside a .pipe()
You had a side effect (discussed above) and you needed to convert the user into a ViewModel (because you needed to know if the user was truthy to decide if require password was true).
Now you could have just done: This is wrong 😦
<form *ngIf="user$ | async as user" [formGroup]="form" (ngSubmit)="onSubmit()">
<app-input-pass [subForm]="form" [require]="user != null"></app-input-pass>
But I think that the ViewModel is more expressive and easier to read. As was your use of isRequirePassword.
Actually ☝️ this wouldn't work because if user was null then *ngIf would hide the form.
Oh, and I've added the loading thing above now.
<form *ngIf="vm$ | async as vm; else loading" [formGroup]="form" (ngSubmit)="onSubmit()">
</form>
<ng-template #loading><div>Loading...</div></ng-template>
I think that's what was happening. 'Cause the data was coming and the data wasn't showing
IIRC you didn't have any *ngIf before. your problem was that you didn't think Asynchronously.
Yup. I have this problem a lot with typescript😬
In your constructor you tried to initialize the form:
//Dados
@Input('user') user?: IUser;
constructor() {
super();
this.user$ = this.authService.getLoggedUser();
this.form = new FormGroup({
id: new FormControl(this.user ? this.user.id : ''),
But this.user wasn't set yet.
especially not set yet because
ngOnInit(): void {
this.loadMyUser();
Happens after the constructor.
But triply not set because
this.user$.subscribe({
next: user => {
if (user.abilities) {
this.user = user;
console.log(this.user);
the next method happens billions of processor instructions after ngOnInit which is further thousands of processor instructions after constructor
constructoris invoked- 1000s of instructions later
ngOnInitis invoked- Billions of instructions later, from your Processor's view weeks will pass
- the
.subscribenextmethod is invoked.
super(); // This is really not a good idea IMPO.``` Why is not a good idea?
Because unless you can explain Prototypial Inheritance (What JavaScript and therefore TypeScript use) then you probably shouldn't be doing inheritance.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
@gusty kernel Thank you for your help! 🙏🏿
The other thread that you also helped me with worked as well.
Jeff Atwood (2007) - Your Code: OOP or POO?
"OO seems to bring at least as many problems to the table as it solves."
Eric Allman (2011) - Programming Isn't Fun Any More
"I used to be enamored of object-oriented programming. I'm now finding myself leaning toward believing that it is a plot designed to destroy joy. The methodology looks clean and elegant at first, but when you actually get into real programs they rapidly turn into horrid messes."
[Richard Mansfield] - WhitePaperHasOOPFailed.pdf (http://4js.com/files/documents/products/genero/WhitePaperHasOOPFailed.pdf)
OOP has taken over computer "science" departments to the exclusion of any alternative programming system. A generation of programmers has graduated from schools that teach only the OOP way, so that’s what they tend to prefer. It's really all they know. They memorize a set of “best practices” (abstract design rules) to help them grind out OOP without making too many mistakes. OOP can be effective to some extent during the initial design phase--when a program’s broad goals and large-scale structure is being imagined and sketched in. However, for day-do-day code writing, OOP is generally the single biggest obstacle to contemporary programmer productivity. Are results achieved faster? No, creating programs usually takes considerably longer than it does with more natural languages and more sensible approaches to modular design. Have bugs been reduced? No, they usually increase. Is program maintenance easier? No, OOP and C languages are notoriously counterintuitive and difficult to read.
A tale of growing frustration with Object-Oriented Programming that highlights one of its core features as a culprit
!Close