To get Id for edit functionality in angular - javascript

I have created a popup for edit functionality in my todo app and I need to get the id of the task for the purpose. using route is not giving a correct result. Is there any other way I can achieve it? I have given the code below.
this.id = this.route.snapshot.params['id'];
console.log(this.formData.value);
this.todoService.editTasks(this.id, this.formData.value).subscribe((res: any)=>{
console.log('update successful');
// this.router.navigateByUrl('/tasks');
})
}```

verfiy that you have the same id in the path of edit component :
{path: "edit/:id", component: someComponent}
use that in the component
import { ActivatedRoute } from '#angular/router';
constructor(private route: ActivatedRoute) {}
ngOnInit(){
//you need to unsubscribe in the ngOnDestroy
this.subscription = this.route.paramMap.subscribe(params=> {
//i use + to convert the id to a number type
let id =+params.get('id');
}
//To prevent memory leak
ngOnDestroy(): void {
if (this.subscription)
this.subscription.unsubscribe()
}
or use that :
ngOnInit(){
let id =this.route.snapshot.paramMap.get('id');
}
use the Angular doc : https://angular.io/tutorial/toh-pt5#extract-the-id-route-parameter

You need to use ActivatedRoute in order to get the id from the URL, check the following steps to use it.
// import
import { ActivatedRoute } from '#angular/router';
//dependency injection
constructor(private route: ActivatedRoute) { }
//implementation
ngOnInit() {
this.route.paramMap.subscribe(
params => {
this.id= params.get('id'); // This is the required Id
})
}
I hope this answers your question, Let me know if I got something wrong.

Related

How can I make the product I`m clicking on to get deleted?

I need some help with this product getting deleted, can`t quite figure this out.
I know what has to be done on the back-end, I need some help with Angular to make this button work only with the product it has been clicked on
Thanks
This is how I intend to delete it on the back end service :
async function deleteProduct(_id){
return Product.findByIdAndDelete(_id)
}
Nothing on the controller yet :
productController.get(`/profile/delete`, async(req,res) => {
})
This is angular component :
import { Component, OnInit } from '#angular/core';
import { IProduct } from 'src/app/interfaces/products';
import { IUser } from 'src/app/interfaces/user';
import { ProfileService } from './profile.service';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: IUser|undefined
products: IProduct[] | any
isEmpty : boolean = false
constructor(private profileService: ProfileService){
}
ngOnInit(): void {
this.user = undefined
this.products = undefined
this.profileService.getUserDetails().subscribe({
next: (user) => {
this.user = user
this.products = user.products
if(this.products.length == 0){
this.isEmpty = true
}
}
})
}
deleteProduct(){}
}
As you can see most of it is empty, because I dont have any ideas. I dont want to load the page in detailed view or anything. I`d like to have this button working on this page
I assume you have in the template an ngFor (because on the image you have multiple products) and I assume product is an item of the products array. If so, well, you are almost there. You have just to pass the id parameter to the deleteProduct method like this:
deleteProduct(id: number)
{
// call the delete method
}
And don't forget to remove this product from the products array (or reload the array from the backend).

CanActivate Guard doesn't seem to subscribe to observable

I have an angular application which has a number of steps to complete. Each step can only be done once and must have all previous steps complete. To achieve this I have added route guards to each route. The application makes a http request on start to check the status. However the route guard canActivate method doesn't seem to be subscribing to changes.
In the below example statusService updates the status which should trigger an update in the guards.
statusService
#Injectable({
providedIn: 'root'
})
export class StatusService {
private stepOneComplete: BehaviorSubject<boolean> = new BehaviorSubject(false);
private stepTwoComplete: BehaviorSubject<boolean> = new BehaviorSubject(false);
constructor(
private http: HttpClient
) { }
public getStepOneComplete(): Observable<boolean> {
return this.stepOneComplete;
};
public updateStepOneComplete(newValue: boolean): void {
this.stepOneComplete.next(newValue);
};
public initialize(): void {
this.http.get(`${apiUrl}status`)
.subscribe((data: any) => {
this.stepOneComplete(data.stepOne);
});
};
};
stepOneGuard
#Injectable()
export class StepOneGuard implements CanActivate {
constructor(
private service: StatusService,
private router: Router
) {}
canActivate(): Observable<boolean> {
return this.service.getStepOneComplete().pipe(
tap(complete => {
if(complete){
this.router.navigate(['/step-two']);
}
}),
map(complete => {
return !complete;
})
);
}
}
What I expect to happen is that after the initialize method runs and updates stepOneComplete then the router should navigate to step two. However no navigation occurs. If I put a console.log in the tap method of the guard it fires on initial load but not when stepOneComplete.next is called.
I think the answer is here:
public getStepOneComplete(): Observable<boolean> {
return this.stepOneComplete.asObservable();
}
This is what I have in my own production code, works just fine.
You should not see a guard as a singleton that controls navigation. Its only purpose is to control whether the user can access a page or not.
I suggest you to have a state service that holds the state of your "wizard", and then you would simply check it in every guard. You shouldn't even need Subjects at all.

Reading routing parameter in HTML

We can set the routing parameter through HTML:
<a [routerLink] = "['/api/foo/', id]"/>
I know that we can read routing parameter through handling event in the typescript:
import {OnInit, OnDestroy, Component} from '#angular/core';
#Component({...})
export class MyComponent implements OnInit{
constructor(private activatedRoute: ActivatedRoute) {}
ngOnInit() {
// subscribe to router event
this.activatedRoute.params.subscribe((params: Params) => {
let Id = params['id'];
console.log(Id);
});
}
}
However, is there any way to read route parameter in the HTML, not in the TypeScript component?
I would like to use in the following manner:
<a href="api/foo/[routerLink]"/>
If you want to get the param in html it is better to assign the param to a variable and use it in html
private param:number;
private ngOnInit() {
// subscribe to router event
this.activatedRoute.params.subscribe((params: Params) => {
this.param = params['id'];
console.log(this.param);
});
}
in your html
<div>{{param}}</div>
if you want to get id as number. You can use this.
id:number;
ngOnInit() {
this.subscription = this.activatedRoute.params.subscribe(
(params: any) => {
if (params.hasOwnProperty('id')) {
id= +params['id'];
//do whatever you want
}
}
);
}
and this destroyed the subscription
ngOnDestroy() {
this.subscription.unsubscribe();
}
and you can access the id field on html side.

Can't get a route params in angular2

I have a route like this
<a [routerLink]=" ['../projects', project.id] ">
And when i try get a route parameter from this url i don't get anything.
My import:
import { Component} from '#angular/core';
import { ActivatedRoute } from '#angular/router';
My constructor:
constructor(private route: ActivatedRoute) {}
My on init:
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
console.log(params); //there i get only empty Object with `__proto__`
});
}
}
Who can help me with this?
Use snapshot to get the route parameter.
let id = +this.route.snapshot.params['id'];
//do something here

Angular2 component doesn't detect routing parameter updates (Router 3.0)

I've got a small Plunk I'm using for playing around with the new Router 3.0 alpha currently available in Angular 2. It works well in general, but the issue is that once I click on a link that routes to the 'detail' component with a particular ID, it never changes when I click on a different link with a different ID. The component is never being reinstantiated, so it only ever shows what it was passed the very first time it is loaded.
Here's the component in question:
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { ContactsService } from './contacts.service';
#Component({
selector: 'contacts-detail',
template: `
<h2>{{contact.name}}</h2>
`
})
export class ContactsDetailComponent implements OnInit {
constructor(private contactsService: ContactsService, private route: ActivatedRoute) {
}
ngOnInit() {
this.contact = this.contactsService.getContact(this.route.snapshot.params.id);
console.log('Fetching user', this.route.snapshot.params.id);
}
}
Here is the Plunk demonstrating the problem. Click on one author name and then another to see it not change.
In your ContactsDetailComponent, change the OnInit to this:
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
let id = +params['id'];
this.contact = this.contactsService.getContact(id);
});
}
Worked for me in your Plunk.
There appear to be multiple lifeCycle hooks that could possibly be used for this. I managed to get the desired behavior using the DoCheck interface and implementing the associated ngDoCheck() method in the component class, as seen below.
import { Component, DoCheck } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { ContactsService } from './contacts.service';
#Component({
selector: 'contacts-detail',
template: `
<h2>{{contact.name}}</h2>
`
})
export class ContactsDetailComponent implements AfterViewChecked, DoCheck {
constructor(private contactsService: ContactsService, private route: ActivatedRoute) {
}
ngDoCheck() {
this.contact = this.contactsService.getContact(this.route.snapshot.params.id);
}
}
Here's a plunk with the updated code.
I'm not convinced this is the best/correct lifecycle hook to use, though. Perhaps there is some sort of hook available from the Router that would serve this better.
Another way to do this:
ngOnInit() {
this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.contact = this.contactsService.getContact(id);
});
}
Here retrieve the route params from an Observable. The advantage of using an Observable over Snapshot is to reuse the component without instantiating it again. Looks like this is the recommended way of doing this as per Angular 2.0 final documentation.

Categories

Resources