I have been learning Angular 2
I have currently implemented Components as content.
I have a table on my Bug-list.component.html which connects to firebase 3
reads data from the bug table and displays this data within the table using *ngFor
as shown here:
When I click + Add Bug
button, the ngbModal
appears which allows me to enter new data and press save which then saves to firebase
- note: this is working as expected.
This issue:
What I'm trying to achieve is when the user presses edit
on either of the rows, I pass in the uniqueId for the bug and try to pre-populate the ngbModal
with information about that bug, which then allows the end user to edit it / save it or delete it, I do this using the routerlink as shown here:
<a [routerLink]="['/bug-detail', 1]">
Edit
</a>
However when I click on 'Edit' this is the current error message I see within the console:
I also tried navigating programmatically but the same error appears.
Now inside the component I'm loading via the ngbModal
this is the .ts
file:
** Bug Detail Component ** - Displaying content about individual bugs, which is loaded via ngbModal
.
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
// Routing
import { ActivatedRoute } from '@angular/router';
// Bootstrap
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
// Forms
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
// Services
import { BugService } from '../bugs/service/bug.service';
// Models
import { Bug } from '../bugs/model/bug';
// Validators
import { forbiddenStringValidator } from '../shared/validation/forbidden-string.validator';
@Component({
selector: 'bug-detail',
templateUrl: './bug-detail.component.html',
styleUrls: ['./bug-detail.component.css']
})
export class BugDetailComponent implements OnInit {
private bugForm: FormGroup;
private id: number;
private sub: any;
@Input() currentBug = new Bug(null, null, null, null, null, null, null, null, null);
constructor(private formBuilder: FormBuilder, private bugService: BugService, private route: ActivatedRoute, public activeModal: NgbActiveModal) { }
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.id = +params['id']; // (+) converts string 'id' to a number
console.log(this.id);
});
this.configureForm();
}
ngOnDestroy() {
this.sub.unsubscribe();
}
configureForm() {
this.bugForm = new FormGroup({
title: new FormControl(null, Validators.required),
status: new FormControl(1, Validators.required),
severity: new FormControl(1, Validators.required),
description: new FormControl(null, Validators.required)
});
}
submitForm() {
this.addBug();
}
addBug() {
this.currentBug.title = this.bugForm.value["title"];
this.currentBug.status = this.bugForm.value["status"];
this.currentBug.severity = this.bugForm.value["severity"];
this.currentBug.description = this.bugForm.value["description"];
this.bugService.addBug(this.currentBug);
this.activeModal.close();
}
}
As you can see I have imported the NgbActiveModal
inside the constructor for this component.
Now this is my bug-list.component.ts
: - Displays all bugs on the table, and when + Add Bug
is clicked, it calls the open
function.
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { BugService } from '../service/bug.service';
import { Bug } from '../model/bug';
import { NgbModal, NgbActiveModal, NgbModalRef, NgbModalOptions } from '@ng-bootstrap/ng-bootstrap';
import { BugDetailComponent } from '../../bug-detail/bug-detail.component';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
selector: 'bug-list',
templateUrl: './bug-list.component.html',
styleUrls: ['./bug-list.component.css']
})
export class BugListComponent implements OnInit {
private bugs: Bug[] = [];
constructor(private bugService: BugService, private cdRef: ChangeDetectorRef, private modalService: NgbModal, private route: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.getAddedBugs();
}
getAddedBugs() {
this.bugService.getAddedBugs().subscribe(bug => {
this.bugs.push(bug);
this.cdRef.detectChanges();
},
err => {
console.error("unable to get added bug - ", err);
});
}
open(options: NgbModalOptions = { size: 'lg' }): NgbModalRef {
const modalRef = this.modalService.open(BugDetailComponent, options);
modalRef.componentInstance.name = 'bugDetail';
return modalRef;
}
}
So my question is, how can I pass in the ID
of the bug clicked into the bug-detail.compoenent
, populate that component with values linked to that bug and then display the modal again, allowing the user to edit / delete.
Surely there must be a way to pass in a uniqueId, populate the fields on the ngbModal and then display it.
Update
Ok so after following component communication I created a service:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class BugCommunication {
// Literally copied straight from example.
private missionAnnouncedSource = new Subject<string>();
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
announceMission(mission: string) {
this.missionAnnouncedSource.next(mission);
console.log(mission);
}
}
This service is injected into Bug-list.component.ts
when the user clicks edit, I then call the above service passing in a value as shown here:
editBug(bug: Bug) {
let mission = "Testing sevice";
this.comServe.announceMission(mission);
this.history.push(`Mission "${mission}" announced`);
}
Note: comServe is the name of the service mentioned above after it's been imported.
The service then console.logs "Testing service".
Inside my bug-detail.component.ts
I subscribe to the above event as shown here:
ngOnInit() {
this.subscription = this.comServe.missionAnnounced$.subscribe(
mission => {
console.log(mission);
});
this.configureForm();
}
However whenever I click on the edit button and call the service, bug-detail.component
does not log anything to the console.
I have correctly imported this service into the Module
, can someone explain what I'm doing wrong?
It sounds like your subscribe method isn't receiving the .next() value from your service.
I believe it's because your observable is observing to the mission property, while your service is sending the message as an unnamed property. Aka: next(string) Two sections of your code that will need to change
bug-detail.component.ts
BugCommunication
Here's a solid example: http://jasonwatmore.com/post/2016/12/01/angular-2-communicating-between-components-with-observable-subject