Angular 14 sevice added to component provider is not available to dynamic NullInjectorError: No Provider for ResponseService - angular14

I am having a component and injecting the service to component providers array. Onclick of a button i am opening a side bar component. Getting error saying NullInjectorError: No Provider for ResponseService! Can anyone help me how to fix this error?
Parent component:
#Component({
selector: 'app-question',
templateUrl: './question.component.html',
styleUrls: ['./question.component.scss'],
providers: [ResponseService]
})
export class QuestionComponent {
ngOnInit() {
this._reponseService.mandatorySections$.pipe(
takeUntil(this._destroy$)
).subscribe(count => {
console.log('total mandatory count', count);
this.totalMandatoryActions = count;
})
}
}
showSidebar(): void {
this._sidebar.open(ResponseComponent, {
header: 'Manage Response Type',
data: {
itemId: this._item.id,
attributes: this._item.attributes
},
disableAutoClose: true
});
}
Dynamic component:
#Component({
selector: 'app-mandatory-response',
templateUrl: './mandatory-response.component.html',
styleUrls: ['./mandatory-response.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ResponseComponent {
public save(isSidebarClose = true): void {
this._mandatoryReponseService.setMandatorySections(this.sourceAttributes.questionMandatoryOptions);
if (isSidebarClose) this._sidebarService.close();
}
}
Thanks

Related

How to navigate between pages in ionic 4 & 5?

I had a project that I developed with ionic 3. But I took a break and when I started working again with ionic, I saw the navigation system change in the new versions. My project is a simple project. This project that lists the data in the a array and details about the data appear on a different page.
I was doing this on Ionic 3:
homepage.ts
export class HomePage {
items = [];
constructor(public navCtrl: NavController) {
this.initializeItems();}
initializeItems() {
this.items = [
{
'title': 'John',
'image': '',
'hair': 'black',
},
{
'title': 'Brendon',
'image': '',
'hair': 'blonde',
}];
openNavDetailsPage(item) {
this.navCtrl.push(DetailsPage, { item: item });
}
detailspage.ts
export class DetailsPage {
item;
constructor(params: NavParams) {
this.item = params.data.item;
}
}
NavCtrl and NavParams are no longer available in version 5 (and I think in version 4). I did to navigate from the home page to the next page(ionic 5).
homepage.ts:
toDetailsPage(){
this.router.navigate(['details'])
}
However, I couldn't navigate according to the data on my list. How can I do this according to the next generation version?
app.routing.module.ts (Routing Module)
const itemRoutes: Routes = [
{ path: 'item', component: ItemListComponent},
{ path: 'DetailsPage/:id', component: DetailComponent }
];
homepage.ts file
import { Router } from '#angular/router';
export class HomePage {
constructor(private router: Router)
openNavDetailsPage(item) {
this.router.navigate(['/DetailsPage', { item: item }]);
}
}
.html file
If you directly want to route through html page:
<ion-button routerLink="/DetailsPage">Log In </ion-button>
or
<ion-button [routerLink]="['/DetailsPage', item.id]">Log In </ion-button>
detail.ts file
import { ActivatedRoute, Router } from '#angular/router';
export class DetailComponent implements OnInit {
id: any;
constructor(private route: ActivatedRoute,
private router: Router) { }
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
}
}
In addition to using a JSON
homepage.ts file
this.router.navigate(['/DetailsPage', { item: JSON.stringify(item) }]);
detail.ts file
this.item = JSON.parse(this.route.snapshot.paramMap.get('item'));
one more way
homepage.html
<div *ngFor=""let item of items"> // here items is an array
<button (click)="goToDetail(item)" class="rgt-btn">
<ion-icon slot="icon-only" name="add-circle" ></ion-icon>
</button>
</div>
homepage.ts
import { NavigationExtras, Router } from '#angular/router';
export class HomePage {
constructor(private router: Router)
goToDetail(item){
let navigationExtras: NavigationExtras = item;
this.router.navigate(['/DetailsPage'], navigationExtras);
}
}
DetailsPage.ts
import { Router } from '#angular/router';
export class DetailComponent implements OnInit {
item: any;
constructor(private router: Router) {
if (this.router.getCurrentNavigation()) {
this.item = this.router.getCurrentNavigation().extras;
}
}
}
> OR With the help of service page
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class NavExtrasService {
extras: any;
constructor() { }
public setExtras(data){
this.extras = data;
}
public getExtras(){
return this.extras;
}
}
Let's say I'm navigating from home to detail page, In page A:
this.navExtras.setExtras(extras)
this.router.navigateByUrl('detailPage');
Then in Detail Page, I retrieve the extras this way:
let newData: any;
this.newData = navExtras.getExtras();

Angular 5 input output

In my application there is a toolbar in the a navigation component. This navigation component is part of the app.component along with the place for other components to show. I have a login page from where I want to transfer a variable to the app.component and then on the basis of the variable the toolbar should be changed. From login component I am transferring the variable through #output and eventemitter but in app.component I am not receiving it. The code is as follows.
app.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
myrole = 'NoUser';
ngOnInit() {
console.log(this.myrole);
}
}
login.component.ts
import { Component, OnInit, Output, EventEmitter } from '#angular/core';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
Name: string;
Pass: string;
#Output() myrole = new EventEmitter();
constructor(private rout: Router) { }
ngOnInit() {
}
OnName(event: any)
{
this.Name = event.target.value;
if (this.Name === 'admin' || this.Name === 'Admin') {
this.myrole.emit('admin');
} else if (this.Name === 'user' || this.Name === 'User') {
this.myrole.emit('user');
} else {
this.myrole.emit('NoUser');
}
console.log(this.myrole);
}
onPass(event: any)
{
this.Pass = event.target.value;
}
Submit() {
this.rout.navigate(['*']);
}
}
navi.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-navi',
templateUrl: './navi.component.html',
styleUrls: ['./navi.component.css']
})
export class NaviComponent implements OnInit {
#Input() myrole: string;
ngOnInit(): void {
console.log(this.myrole);
}
}
app.component.html
<app-navi [myrole]='myrole'></app-navi>
<br>
<router-outlet></router-outlet>

Angular 5: ERROR TypeError: Cannot read property 'offset' of undefined

Error:
ERROR TypeError: Cannot read property 'offset' of undefined
I had comic component, was working fine, but I decided to make a child component, and now it's not working.
I have a parent component 'comics', and a child component 'pagination'. The comics are displayed fine, but the pagination is not working.
In the code, the console.log(this.pagination); is returning an array like ('offset': 20, 'count':1)
But pagination.component.html ir returning an error Cannot read property 'offset' of undefined so pagination is empty, has no data. So parent comics.component.ts is not sharing this variable with child.
I tried to declare pagination: Pagination; in pagination.component.ts but pagination is still empty.
So I think I'm declaring something in a wrong mode, or I should declare something I'm not declaring. I searched, and I tried to find what's missing but I did not find anything and it's still not working.
my code:
// file: pagination.ts
export class Pagination {
offset: number;
count: number;
}
// file: /comics/comics.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
import { Comic } from '../comic';
import { Pagination } from '../pagination';
import { ComicService } from '../comic.service';
#Component({
selector: 'app-comics',
templateUrl: './comics.component.html',
styleUrls: ['./comics.component.css']
})
export class ComicsComponent implements OnInit {
comics: Comic;
pagination: Pagination;
constructor(
private route: ActivatedRoute,
private comicService: ComicService
) {}
ngOnInit() {
}
getComics(): void {
const offset = +this.route.snapshot.paramMap.get('offset');
this.comicService.getComics(offset, 20)
.subscribe(
result => {
this.comics = result['data']['results'];
console.log(this.comics);
this.pagination.offset = result['data']['offset'];
this.pagination.count = result['data']['count'];
console.log(this.pagination);
}
);
}
}
// file: /pagination/pagination.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
import { Pagination } from '../pagination';
#Component({
selector: 'app-pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
// file: comics/comics.component.html
<div *ngFor="let comic of comics">
<h5>{{comic.title | uppercase}} </h5>
</div>
<app-pagination></app-pagination>
// file: pagination/pagination.component.html
<div>
<h5>{{pagination.offset}}</h5>
<span>{{pagination.count}}</span>
</div>
Versions used:
Angular CLI: 1.7.3
Node: 8.9.4
OS: darwin x64
Angular: 5.2.8
Given that these two components are in a parent-child relationship, your best option is to simply define offset and count as input properties for the child component, and pass them from the parent, like this:
comics.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
import { Comic } from '../comic';
import { Pagination } from '../pagination';
import { ComicService } from '../comic.service';
#Component({
selector: 'app-comics',
templateUrl: './comics.component.html',
styleUrls: ['./comics.component.css']
})
export class ComicsComponent implements OnInit {
comics: Comic;
offset;
count;
constructor(
private route: ActivatedRoute,
private comicService: ComicService
) {}
ngOnInit() {
}
getComics(): void {
const offset = +this.route.snapshot.paramMap.get('offset');
this.comicService.getComics(offset, 20)
.subscribe(
result => {
this.comics = result['data']['results'];
console.log(this.comics);
this.offset = result['data']['offset'];
this.count = result['data']['count'];
}
);
}
}
pagination.component.ts
import { Component, OnInit, Input } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
import { Pagination } from '../pagination';
#Component({
selector: 'app-pagination',
templateUrl: './pagination.component.html',
styleUrls: ['./pagination.component.css']
})
export class PaginationComponent implements OnInit {
#Input() offset;
#Input() count;
constructor() { }
ngOnInit() {
}
}
comics.component.html
<div *ngFor="let comic of comics">
<h5>{{comic.title | uppercase}} </h5>
</div>
<app-pagination [offset]="offset" [count]="count"></app-pagination>
pagination.component.html
<div>
<h5>{{offset}}</h5>
<span>{{count}}</span>
</div>

Creating restricted members area in Angular Fire 2

I am trying to make an application using angularfire 2. Can't find the perfect way to make the members area restricted that means only authenticated members can access that area. Here is my 'login.component.ts' file
import { Component, OnInit, HostBinding } from '#angular/core';
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2';
import { FormControl, FormGroup, Validators } from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class LoginComponent {
state: string = '';
error: any;
login: FormGroup;
constructor(
public af: AngularFire,
private router: Router
) {
//official angfire 2 app example
//this.af.auth.subscribe(auth => console.log(auth));
}
ngOnInit() {
this.login = new FormGroup({
username: new FormControl('', Validators.required),
password: new FormControl('', Validators.required)
});
}
onSubmit() {
//console.log(this.login.value, this.login.valid);
var value = this.login.value;
//console.log(value.username);
//console.log(value.password);
this.af.auth.login({
email: value.username,
password: value.password,
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password,
}).then(
(success) => {
console.log(success);
this.router.navigate(['/members']);
}).catch(
(err) => {
console.log(err);
this.error = err;
})
}
}
and the members.component.ts file
import { Component, OnInit } from '#angular/core';
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2';
import { Router } from '#angular/router';
#Component({
selector: 'app-other',
templateUrl: './members.component.html',
styleUrls: ['./members.component.css']
})
export class MembersComponent implements OnInit {
//name: "";
//state: string = '';
constructor(
public af: AngularFire,
private router: Router
) {
this.af.auth.subscribe(auth => {
if(auth) {
console.log(auth);
}
});
}
logout() {
this.af.auth.logout();
console.log('logged out');
this.router.navigate(['/login']);
}
ngOnInit() {
}
}
I know my code may be seem like a dumb one but actually I am trying to study over this. But there is not enough documentation to solve my problem I guess. Thanks in advance.
https://coursetro.com/posts/code/32/Create-a-Full-Angular-Authentication-System-with-Firebase
this is a great tutorial that solves your problem

Angular 2 error after authentication - Cannot find primary outlet to load

I have an error in console after authentication. After reload page CreateChartComponent page start working. Error just happen in authentication process.
Uncaught (in promise): Error: Cannot find primary outlet to load 'CreateChartComponent'
This is the login function.
login(event, username, password): void {
event.preventDefault();
this.authService.login(username, password).subscribe(
res => {
this.router.navigate(['drawing']);
},
err => {
// todo: handle error with a lable
console.log(err);
if (err.ok === false) {
this.errorMessage = 'Error logging in.';
}
});
}
}
Aditional information:
I send clear mode of code where I get same issue.
It's Router code:
// Import our dependencies
import { Routes } from '#angular/router';
import { AppComponent } from './app.component';
import { LoginComponent } from './home/login/login.component';
import { CreateChartComponent } from './home/drawing/create-chart.component';
import { AuthGuard } from './auth.guard';
// Define which component should be loaded based on the current URL
export const routes: Routes = [
{ path: '', component: CreateChartComponent, pathMatch: 'full', canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: 'drawing', component: CreateChartComponent, canActivate: [AuthGuard] },
];
and its create-chart.component.ts
import {
Component,
OnInit,
} from '#angular/core';
#Component({
selector: 'np-chart-create',
templateUrl: './create-chart.component.html',
styleUrls: ['./create-chart.component.css']
})
export class CreateChartComponent implements OnInit {
ngOnInit() {
}
}