API is being called twice when using feature module Angular 8 - angular8

As per Angular documentation, I have done the following steps.
Added CommonModule in the Feature Module(not BrowserModule).
Used ProvidedIn: 'root'
Here is what I have done so far.
AppModule
import { BrowserModule, Title } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { HTTP_INTERCEPTORS } from '#angular/common/http';
import { MatFormFieldModule } from '#angular/material/form-field';
import { MatStepperModule } from '#angular/material/stepper';
import { MatInputModule } from '#angular/material/input';
import { MatCheckboxModule } from '#angular/material/checkbox';
import { MatDatepickerModule } from '#angular/material/datepicker';
import { MatRadioModule } from '#angular/material/radio';
import { MatSelectModule } from '#angular/material/select';
import { MatSlideToggleModule } from '#angular/material/slide-toggle';
import { MatMenuModule } from '#angular/material/menu';
import { MatSidenavModule } from '#angular/material/sidenav';
import { MatToolbarModule } from '#angular/material/toolbar';
import { MatCardModule } from '#angular/material/card';
import { MatButtonModule } from '#angular/material/button';
import { MatIconModule } from '#angular/material/icon';
import { MatProgressBarModule } from '#angular/material/progress-bar';
import { MatDialogModule } from '#angular/material/dialog';
import { MatSnackBarModule } from '#angular/material/snack-bar';
import { MatPaginatorModule } from '#angular/material/paginator';
import { MatSortModule } from '#angular/material/sort';
import { MatTableModule } from '#angular/material/table';
import { MatListModule } from '#angular/material/list';
import {
MatNativeDateModule,
MatAutocompleteModule
} from '#angular/material';
import { MatProgressSpinnerModule } from '#angular/material/progress-spinner';
import { MatGridListModule } from '#angular/material/grid-list';
import { MatChipsModule } from '#angular/material/chips';
import { MatExpansionModule } from '#angular/material/expansion';
import { MatTabsModule } from '#angular/material/tabs';
// import { AppraisalModule } from './feature-modules/yearly-appraisal/appraisal.module';
import { AuthService } from './auth.service';
import { SensitiveService } from './services/sensitive.service';
import { ErrorService } from './classes/error';
import { UserService } from './services/user.service';
import { ExcelService } from './services/excel.service';
import { AuthGuard } from './auth.guard';
import { ProjectService } from './services/project.service';
import { InterviewService } from './services/interview.service';
import { KickoffService } from './services/kickoff.service'
import { AppComponent } from './app.component';
import { LoginComponent } from './dashboard/auth/login/login.component';
import { ForgotPasswordComponent } from './dashboard/auth/forgot-password/forgot-password.component';
import {
UserComponent,
// DialogAddUserComponent,
DialogDeleteUserComponent,
DialogChangeStatusComponent
} from './dashboard/user/user.component';
import { ViewComponent } from './dashboard/view/view.component';
import { CreatePasswordComponent } from './dashboard/auth/create-password/create-password.component';
import {
ToolbarComponent,
DialogLoaderComponent
} from './dashboard/shell/toolbar/toolbar.component';
import { SideNavComponent } from './dashboard/shell/side-nav/side-nav.component';
import { FilterComponent } from './dashboard/filter/filter.component';
import { CandidateListComponent } from './dashboard/candidate-list/candidate-list.component';
import { CandidateFiltersComponent } from './dashboard/candidate-filters/candidate-filters.component';
import { LoaderDownloadComponent } from './dialogs/loader-download/loader-download.component';
import { AdvancedFiltersComponent } from './components/advanced-filters/advanced-filters.component';
import { ProjectAddComponent } from './components/projects/project-add/project-add.component';
import { ProjectListComponent } from './components/projects/project-list/project-list.component';
import { LoaderComponent } from './dialogs/loader/loader.component';
import { ErrorComponent } from './dialogs/error/error.component';
import { SuccessComponent } from './dialogs/success/success.component';
import { ConfirmationComponent } from './dialogs/confirmation/confirmation.component';
import { MatDividerModule } from '#angular/material/divider';
import { AgoPipe } from './pipes/ago.pipe';
import { TimeAgoPipe } from 'time-ago-pipe';
import { MoveProjectComponent } from './dialogs/move-project/move-project.component';
import { CandidateService } from './services/candidate.service';
import { MatTooltipModule } from '#angular/material/tooltip';
import { RemoveApplicantComponent } from './dialogs/remove-applicant/remove-applicant.component';
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
import { InterviewListComponent } from './components/interviews/interview-list/interview-list.component';
import { MoveInterviewComponent } from './dialogs/move-interview/move-interview.component';
import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
import { InterviewStatusComponent } from './dialogs/interview-status/interview-status.component';
import { HrComponent } from './components/hr/hr.component';
import { AssignHrComponent } from './dialogs/assign-hr/assign-hr.component';
import { HrService } from './services/hr.service';
import { LoiComponent } from './dialogs/loi/loi.component';
import { OfferLetterComponent } from './dialogs/offer-letter/offer-letter.component';
import { FinalStepComponent } from './dialogs/final-step/final-step.component';
import { FeedbackComponent } from './components/feedback/feedback.component';
import { InterviewFeedbackShowComponent } from './dialogs/interview-feedback-show/interview-feedback-show.component';
import { InterviewerProfileComponent } from './components/interviewer-profile/interviewer-profile.component';
import { AddInterviewerComponent } from './components/add-interviewer/add-interviewer.component';
import { RecruitmentSummaryFiltersComponent } from './components/recruitment-summary-filters/recruitment-summary-filters.component';
// import { InterviewRoundTwoComponent } from './dialogs/interview-round-two/interview-round-two.component';
// import { InterviewRoundTwoFeedbackComponent } from './dialogs/interview-round-two-feedback/interview-round-two-feedback.component';
// tslint:disable-next-line:max-line-length
// import { InterviewRoundTwoFeedbackShowComponent } from './dialogs/interview-round-two-feedback-show/interview-round-two-feedback-show.component';
import { MatRippleModule } from '#angular/material/core';
import { SideNavLatestComponent } from './components/side-nav-latest/side-nav-latest.component';
import { FooterComponent } from './shell/footer/footer.component';
import { JobPostingComponent } from './components/job-posting/job-posting.component';
import { JobPostingCreateComponent } from './components/job-posting-create/job-posting-create.component';
import { CKEditorModule } from '#ckeditor/ckeditor5-angular';
import { AssignProjectComponent } from './dialogs/assign-project/assign-project.component';
import { CarouselModule } from 'ngx-owl-carousel-o';
import { NodataComponent } from './utilities/nodata/nodata.component';
import { ScreeningComponent } from './utilities/screening/screening.component';
import { EngagedViewComponent } from './dialogs/engaged-view/engaged-view.component';
import { RejectLoiComponent } from './dialogs/reject-loi/reject-loi.component';
import { MoveApplicantComponent } from './dialogs/move-applicant/move-applicant.component';
import { DialogExampleComponent } from './dialogs/dialog-example/dialog-example.component';
import { MakeJobLiveComponent } from './dialogs/make-job-live/make-job-live.component';
import { DragDropModule } from '#angular/cdk/drag-drop';
import { VerifyDocumentsComponent } from './dialogs/verify-documents/verify-documents.component';
import { CheckDocumentsComponent } from './components/check-documents/check-documents.component';
import { SuggestOfferComponent } from './hr/suggest-offer/suggest-offer.component';
import { AddUserComponent } from './dashboard/add-user/add-user.component';
import { EditUserComponent } from './dashboard/edit-user/edit-user.component';
// import { ChangeStatusComponent } from './dashboard/edit-user/edit-user.component';
// import { ChartsModule, ThemeService } from 'ng2-charts';
//import { AppraisalProgressComponent } from './components/appraisal-progress/appraisal-progress.component';
// import { UpdateEmpMappingComponent } from './dialogs/update-emp-mapping/update-emp-mapping.component';
import { BottomSheetComponent } from './dialogs/bottom-sheet/bottom-sheet.component';
//import { ScheduleMeetingComponent } from './dialogs/schedule-meeting/schedule-meeting.component';
//import { EmployeeSefComponent } from './dialogs/employee-sef/employee-sef.component';
//import { AppraisalIssueShowComponent } from './dialogs/appraisal-issue-show/appraisal-issue-show.component';
// import { SefFeedbackFormComponent } from './dialogs/sef-feedback-form/sef-feedback-form.component';
#NgModule({
declarations: [
AppComponent,
LoginComponent,
ForgotPasswordComponent,
UserComponent,
ViewComponent,
CreatePasswordComponent,
ToolbarComponent,
SideNavComponent,
DialogLoaderComponent,
// DialogAddUserComponent,
DialogChangeStatusComponent,
DialogDeleteUserComponent,
FilterComponent,
CandidateListComponent,
CandidateFiltersComponent,
LoaderDownloadComponent,
AdvancedFiltersComponent,
ProjectAddComponent,
ProjectListComponent,
LoaderComponent,
ErrorComponent,
SuccessComponent,
ConfirmationComponent,
AgoPipe,
TimeAgoPipe,
MoveProjectComponent,
RemoveApplicantComponent,
InterviewListComponent,
MoveInterviewComponent,
InterviewStatusComponent,
HrComponent,
AssignHrComponent,
LoiComponent,
OfferLetterComponent,
FinalStepComponent,
FeedbackComponent,
InterviewFeedbackShowComponent,
InterviewerProfileComponent,
AddInterviewerComponent,
RecruitmentSummaryFiltersComponent,
// InterviewRoundTwoComponent,
// InterviewRoundTwoFeedbackComponent,
// InterviewRoundTwoFeedbackShowComponent,
SideNavLatestComponent,
FooterComponent,
JobPostingComponent,
JobPostingCreateComponent,
AssignProjectComponent,
NodataComponent,
ScreeningComponent,
EngagedViewComponent,
RejectLoiComponent,
MoveApplicantComponent,
DialogExampleComponent,
MakeJobLiveComponent,
VerifyDocumentsComponent,
CheckDocumentsComponent,
SuggestOfferComponent,
AddUserComponent,
EditUserComponent,
//AppraisalProgressComponent,
//UpdateEmpMappingComponent,
BottomSheetComponent,
//ScheduleMeetingComponent,
//EmployeeSefComponent,
//AppraisalIssueShowComponent,
//SefFeedbackFormComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
MatCheckboxModule,
MatDatepickerModule,
MatRadioModule,
MatSelectModule,
MatSlideToggleModule,
MatMenuModule,
MatSidenavModule,
MatToolbarModule,
MatCardModule,
MatButtonModule,
MatIconModule,
MatProgressBarModule,
MatDialogModule,
MatSnackBarModule,
MatPaginatorModule,
MatSortModule,
MatTableModule,
HttpClientModule,
MatListModule,
MatNativeDateModule,
MatProgressSpinnerModule,
MatGridListModule,
MatSlideToggleModule,
MatChipsModule,
MatExpansionModule,
MatAutocompleteModule,
MatStepperModule,
MatTabsModule,
MatDividerModule,
MatTooltipModule,
NgxMatSelectSearchModule,
NgxMaterialTimepickerModule,
MatRippleModule,
CKEditorModule,
CarouselModule,
DragDropModule,
// ChartsModule,
// AppraisalModule
],
providers: [
AuthService,
SensitiveService,
ErrorService,
UserService,
AuthGuard,
ExcelService,
ProjectService,
CandidateService,
InterviewService,
HrService,
Title,
// ThemeService,
{
multi: true,
provide: HTTP_INTERCEPTORS,
useClass: KickoffService,
}
],
entryComponents: [
// DialogAddUserComponent,
DialogDeleteUserComponent,
DialogLoaderComponent,
LoaderDownloadComponent,
LoaderComponent,
ErrorComponent,
SuccessComponent,
ConfirmationComponent,
RejectLoiComponent,
MoveProjectComponent,
MoveApplicantComponent,
RemoveApplicantComponent,
MoveInterviewComponent,
InterviewStatusComponent,
AssignHrComponent,
LoiComponent,
OfferLetterComponent,
FinalStepComponent,
InterviewFeedbackShowComponent,
AssignProjectComponent,
EngagedViewComponent,
DialogExampleComponent,
MakeJobLiveComponent,
VerifyDocumentsComponent,
SuggestOfferComponent,
DialogChangeStatusComponent,
//UpdateEmpMappingComponent,
BottomSheetComponent,
//AppraisalProgressComponent,
//ScheduleMeetingComponent,
//EmployeeSefComponent,
//AppraisalIssueShowComponent,
//SefFeedbackFormComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
The feature module --
AppraisalModule
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { AppraisalRoutingModule } from '../yearly-appraisal/appraisal-module-routing.module';
import { AppraisalComponent } from '../yearly-appraisal/appraisal/appraisal.component';
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { MatFormFieldModule } from '#angular/material/form-field';
// import { MatStepperModule } from '#angular/material/stepper';
import { MatInputModule } from '#angular/material/input';
import { MatCheckboxModule } from '#angular/material/checkbox';
import { MatDatepickerModule } from '#angular/material/datepicker';
import { MatRadioModule } from '#angular/material/radio';
import { MatSelectModule } from '#angular/material/select';
import { MatSlideToggleModule } from '#angular/material/slide-toggle';
import { MatMenuModule } from '#angular/material/menu';
// import { MatSidenavModule } from '#angular/material/sidenav';
// import { MatToolbarModule } from '#angular/material/toolbar';
import { MatCardModule } from '#angular/material/card';
import { MatButtonModule } from '#angular/material/button';
import { MatIconModule } from '#angular/material/icon';
// import { MatProgressBarModule } from '#angular/material/progress-bar';
import { MatDialogModule } from '#angular/material/dialog';
import { MatSnackBarModule } from '#angular/material/snack-bar';
import { MatPaginatorModule } from '#angular/material/paginator';
import { MatSortModule } from '#angular/material/sort';
import { MatTableModule } from '#angular/material/table';
import { MatListModule } from '#angular/material/list';
import {
MatNativeDateModule,
MatAutocompleteModule
} from '#angular/material';
import { MatProgressSpinnerModule } from '#angular/material/progress-spinner';
import { MatGridListModule } from '#angular/material/grid-list';
import { MatChipsModule } from '#angular/material/chips';
import { MatExpansionModule } from '#angular/material/expansion';
import { MatTabsModule } from '#angular/material/tabs';
import { MatDividerModule } from '#angular/material/divider';
import { MatTooltipModule } from '#angular/material/tooltip';
import { NgxMatSelectSearchModule } from 'ngx-mat-select-search';
import { NgxMaterialTimepickerModule } from 'ngx-material-timepicker';
import { MatRippleModule } from '#angular/material/core';
import { CKEditorModule } from '#ckeditor/ckeditor5-angular';
import { CarouselModule } from 'ngx-owl-carousel-o';
import { DragDropModule } from '#angular/cdk/drag-drop';
import { ChartsModule } from 'ng2-charts';
import { DeactivateEmpAppraisalComponent } from '../../dialogs/deactivate-emp-appraisal/deactivate-emp-appraisal.component';
import { UpdateEmpMappingComponent } from '../../dialogs/update-emp-mapping/update-emp-mapping.component';
import { ScheduleMeetingComponent } from '../../dialogs/schedule-meeting/schedule-meeting.component';
import { AppraisalIssueShowComponent } from '../../dialogs/appraisal-issue-show/appraisal-issue-show.component';
import { EmployeeSefComponent } from '../../dialogs/employee-sef/employee-sef.component';
import { SefFeedbackFormComponent } from '../../dialogs/sef-feedback-form/sef-feedback-form.component';
#NgModule({
declarations: [
AppraisalComponent,
DeactivateEmpAppraisalComponent,
UpdateEmpMappingComponent,
ScheduleMeetingComponent,
AppraisalIssueShowComponent,
EmployeeSefComponent,
SefFeedbackFormComponent],
imports: [
CommonModule,
AppraisalRoutingModule,
FormsModule,
ReactiveFormsModule,
MatFormFieldModule,
MatInputModule,
MatCheckboxModule,
MatDatepickerModule,
MatRadioModule,
MatSelectModule,
MatSlideToggleModule,
MatMenuModule,
// MatSidenavModule,
// MatToolbarModule,
MatCardModule,
MatButtonModule,
MatIconModule,
// MatProgressBarModule,
MatDialogModule,
MatSnackBarModule,
MatPaginatorModule,
MatSortModule,
MatTableModule,
HttpClientModule,
MatListModule,
MatNativeDateModule,
MatProgressSpinnerModule,
MatGridListModule,
MatSlideToggleModule,
MatChipsModule,
MatExpansionModule,
MatAutocompleteModule,
// MatStepperModule,
MatTabsModule,
MatDividerModule,
MatTooltipModule,
NgxMatSelectSearchModule,
NgxMaterialTimepickerModule,
MatRippleModule,
CKEditorModule,
CarouselModule,
DragDropModule,
ChartsModule
],
entryComponents: [
DeactivateEmpAppraisalComponent,
UpdateEmpMappingComponent,
ScheduleMeetingComponent,
AppraisalIssueShowComponent,
EmployeeSefComponent,
SefFeedbackFormComponent
]
})
export class AppraisalModule { }
ProtocolService
import { Injectable } from '#angular/core';
import {
HttpClient,
HttpHeaders,
HttpParams
} from '#angular/common/http';
import { IVerifyTokenSuccess } from '../interfaces/i-response';
import { API_URL } from '../app.constant';
// import { SensitiveService } from './sensitive.service';
import { Router } from '#angular/router';
import { AuthService } from '../auth.service';
#Injectable({
providedIn: 'root'
})
export class ProtocolService {
constructor(
private http: HttpClient,
private auth: AuthService,
private router: Router
) { }
async checkHandShake() {
const headers = new HttpHeaders()
.set('Content-Type', 'application/x-www-form-urlencoded');
const body: HttpParams = new HttpParams();
const response = await this.http.post(`${API_URL}user/verifytoken`, body.toString(), { headers })
.toPromise()
.then((res:any) => {
// console.log(res);
this.auth.confirmUser(res.result.userinfo);
if (this.router.url === '/user') {
if (res.result.userinfo.super_admin !== '1') {
this.router.navigate(['/view']);
return res.valid as boolean;
}
}
return res.valid as boolean;
}).catch((error: any) => {
this.router.navigate(['/']);
return false;
});
return response;
}
}
AuthGuard
import { Injectable } from '#angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
Router,
} from '#angular/router';
import { Observable } from 'rxjs';
// import { SensitiveService } from './services/sensitive.service';
import { ProtocolService } from './services/protocol.service';
import { IUser } from './interfaces/i-response';
import { map, take } from 'rxjs/operators';
import { AuthService } from './auth.service';
#Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(
private auth: AuthService,
private router: Router,
private _protocol: ProtocolService
) { }
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return this.auth.currentUser.pipe(
take(1),
map((user: IUser) => {
if (!user) {
this._protocol.checkHandShake();
}
return true;
})
);
}
}

Related

Ionic5: setting a footer on all app pages with a sharedModule and controlling it (on/off) from the app.component

I've created a new app using Ionic5 with a menu. I'm trying to use a Footer on multiple pages (now only on Home page). First I've created a SharedModule and imported in the imports' array of the app.module.ts. I've added the footer component in the declarations' and exports' array of the shared.module.ts. Also I added SharedModule in the imports' array of each page.module.ts, and finally adding <app-footer> in each page.html.
It works as expected, showing the footer in all pages. But now I need to control (on/off) this footer from my app.component, in response to a specific event, for example, when internet is not available (this part is not a problem).
footer.component.ts
import { Component, OnInit } from '#angular/core';
import { FooterService } from 'src/app/footer.service';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent implements OnInit {
public FooterEnabled: boolean= false;
constructor() { }
ngOnInit() {
}
}
The FooterEnabled variable control if the footer is showed or not and must be modifiable from the app.component
footer.component.html
<div class="footer-conn" *ngIf="FooterEnabled">
Alert!
</div>
sharedfooter.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FooterComponent } from '../components/footer/footer.component';
#NgModule({
declarations: [FooterComponent],
imports: [
CommonModule
],
exports: [
FooterComponent, CommonModule
]
})
export class SharedFooterModule { }
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { Network } from '#ionic-native/network/ngx';
import { SharedFooterModule } from './shared/sharedfooter.module';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
SharedFooterModule
],
providers: [
StatusBar,
SplashScreen,
Network,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
app.component.ts
import { Component, OnInit } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { Network } from '#ionic-native/network/ngx';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent implements OnInit {
public selectedIndex = 0;
public appPages = [
{
title: 'Página 1',
url: 'home',
icon: 'mail'
},
{
title: 'Página 2',
url: 'pagina2',
icon: 'paper-plane'
},
{
title: 'Página 3',
url: 'pagina3',
icon: 'heart'
}
];
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private network: Network
) {
this.initializeApp();
}// Fin constructor
no_internet() {
alert("No internet!")
// In this point make FooterEnabled = true (from the footer component)
}
si_internet() {
alert("Whith internet!")
//In this point make FooterEnabled = false (from the footer component)
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
ngOnInit() {
let disconnectSubscription = this.network.onDisconnect().subscribe(() => {
setTimeout(() => {
if (this.network.type !== 'none') {
this.si_internet();
}
else {
this.no_internet();
}
}, 1000);
});
// watch network for a connection
let connectSubscription = this.network.onConnect().subscribe(() => {
setTimeout(() => {
if (this.network.type !== 'none') {
this.si_internet();
}
else {
this.no_internet();
}
}, 3000);
});
const path = window.location.pathname.split('/')[1];
if (path !== undefined) {
this.selectedIndex = this.appPages.findIndex(page => page.title.toLowerCase() === path.toLowerCase());
}
}
}
home.module.ts (as an example)
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { IonicModule } from '#ionic/angular';
import { HomePageRoutingModule } from './home-routing.module';
import { HomePage } from './home.page';
import { SharedFooterModule } from '../shared/sharedfooter.module';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HomePageRoutingModule,
SharedFooterModule
],
declarations: [HomePage]
})
export class HomePageModule {}
I've tried with a service imported in the footer.component and app.component.ts that implements observables, but it didn't work. I will appreciate your contributions!!
maybe you can do it like bellow, add input to your footer component :
footer.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent implements OnInit {
#Input() FooterEnabled : string;
//public FooterEnabled: boolean= false;
constructor() { }
ngOnInit() {
}
}
footer.component.ts
<div class="footer-conn" *ngIf="FooterEnabled == 'on'">
Alert!
</div>
on your app.component.ts add new varibale status:
no_internet() {
alert("No internet!")
this.status = 'on'
}
si_internet() {
alert("Whith internet!")
this.status = 'off'
}
put it on app.component.html as :
<app-footer FooterEnabled="status" ></app-footer>

Ionic4: Phonegap-nfc: where is the content?

VERSION: Ionic 4
Plugin: phonegap-nfc
Hi everyone!
I'm trying to use this plugin (https://ionicframework.com/docs/native/nfc) and following the instructions, I should be able to read a message sent from another NFC device. The event is fired and I know something is sent, but I'm not able to understand what and where the message is stored.
This is the code:
home.page.ts
import { Component } from '#angular/core';
import {Ndef, NFC} from '#ionic-native/nfc/ngx';
import {AlertController} from '#ionic/angular';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(private nfc: NFC, private ndef: Ndef, private alertController: AlertController) { }
readNFC() {
this.nfc.addNdefListener(() => {
this.presentAlert('ok');
}, (err) => {
this.presentAlert('ko' + err);
}).subscribe((event) => {
console.log(event);
console.log(JSON.stringify(event));
this.presentAlert('Il messaggio contiene' + event.tag + ' ' + this.nfc.bytesToHexString(event.tag.id));
});
}
writeNFC() {
this.nfc.addNdefListener(() => {
console.log('successfully attached ndef listener');
const message = this.ndef.textRecord('Hello world');
this.nfc.share([message]).then(
value => {
this.presentAlert('ok');
}
).catch(
reason => {
this.presentAlert('ko');
}
);
}, (err) => {
this.presentAlert('ko' + err);
});
}
async presentAlert(mess) {
const alert = await this.alertController.create({
header: 'attenzione',
message: mess,
buttons: ['OK']
});
await alert.present();
}
}
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {Ndef, NFC} from '#ionic-native/nfc/ngx';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
NFC,
Ndef
],
bootstrap: [AppComponent]
})
export class AppModule {}
This is the stringify obtained by printing the content of event:
{"isTrusted":false,"tag":{"id":[0],"techTypes":["android.nfc.tech.Ndef"],"type":"android.ndef.unknown","maxSize":0,"isWritable":false,"ndefMessage":[{"tnf":1,"type":[85],"id":[],"payload":[3,112,108,97,121,46,103,111,111,103,108,101,46,99,111,109,47,115,116,111,114,101,47,97,112,112,115,47,100,101,116,97,105,108,115,63,105,100,61,99,111,109,46,119,97,107,100,101,118,46,119,100,110,102,99,38,102,101,97,116,117,114,101,61,98,101,97,109]},{"tnf":4,"type":[97,110,100,114,111,105,100,46,99,111,109,58,112,107,103],"id":[],"payload":[99,111,109,46,119,97,107,100,101,118,46,119,100,110,102,99]}],"canMakeReadOnly":false}}
Thanks in advance for your help!
Your data is at
ndefMessage[0].payload
you need to use
nfc.bytesToString()
the payload to convert to string

NullInjectorError: No provider for ReducerManager on angular spec file testing

I am testing ngrx/store based component. on test getting NullInjectorError: No provider for ReducerManager
Error message:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
Error: StaticInjectorError(DynamicTestModule)[StoreFeatureModule -> ReducerManager]:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
How to fix this? here is my test spec file:
import { HeaderNavShellComponent } from './header-nav-shell.component';
import { HeaderComponent } from './../../header/header.component';
import { HeaderNavComponent } from './../../components/header-nav/header-nav.component';
import { StoreModule, Store } from '#ngrx/store';
import { TranslateFakeLoader,TranslateLoader,TranslateModule,TranslateService, TranslateStore } from '#ngx-translate/core';
import { RouterTestingModule } from '#angular/router/testing';
import { reducerShared } from "./../../state/reducers/shared.reducer";
import { HttpClientModule, HttpClient } from '#angular/common/http';
import { of } from 'rxjs';
import * as fromRoot from "./../../../calendar/state";
// import { reducerCalendar } from "./../../../calendar/state/calendar.reducer";
describe('HeaderNavShellComponent', () => {
let component: HeaderNavShellComponent;
let fixture: ComponentFixture<HeaderNavShellComponent>;
let dispatchSpy;
let store:Store<fromRoot.NewState>
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeaderNavShellComponent, HeaderComponent, HeaderNavComponent ],
imports:[
HttpClientModule,
StoreModule.forFeature("shared", reducerShared ),
RouterTestingModule,
TranslateModule.forChild({
          loader: {
            provide: TranslateLoader,
            useClass: TranslateFakeLoader
          }
         })
],
providers:[TranslateService, TranslateStore, HttpClient ]
})
.compileComponents();
}));
beforeEach(fakeAsync(() => {
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
fixture = TestBed.createComponent(HeaderNavShellComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', fakeAsync(() => {
expect(component).toBeTruthy();
}));
});
here is the ts file:
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Store, select } from "#ngrx/store";
import { Observable } from "rxjs";
import { ModelEvent, EventState } from "./../../../calendar/models/model.event";
import { ModelLang, ModelLonguage } from "./../../../shared-components/models/models";
import { CalendarActions, Load, EventSelected } from "./../../../calendar/state/calendar.actions";
import * as fromRoot from "./../../../calendar/state";
import * as fromObservables from "./../../state";
import { Lang, LoadLang } from "./../../state/actions/shared.actions";
import { ShowNavi } from "./../../../shared-components/state/actions/shared.actions";
#Component({
selector: 'header-nav-shell',
templateUrl: './header-nav-shell.component.html',
styleUrls: ['./header-nav-shell.component.scss']
})
export class HeaderNavShellComponent implements OnInit {
eventList$:Observable<ModelEvent[]>;
eventListSize$:number;
currentLang$:Observable<string>;
langList$:Observable<ModelLonguage[]>;
constructor(private store:Store<fromRoot.NewState>, private router:Router) { }
ngOnInit() {
this.store.dispatch(new Load());
this.store.dispatch( new LoadLang());
this.eventList$ = this.store.pipe(select(fromRoot.getEvents));
this.currentLang$ = this.store.pipe(select(fromObservables.getCurrentLang));
this.langList$ = this.store.pipe(select(fromObservables.getLangList));
}
eventSelected(event) {
this.store.dispatch(new EventSelected(event));
this.router.navigateByUrl("iboCalendar");
}
langChanged(event) {
this.store.dispatch( new Lang(event.Name));
}
leftNaviHandler(event):void {
this.store.dispatch(new ShowNavi(event));
}
}
Thanks in advance

Error: StaticInjectorError(DynamicTestModule) Angular 5 Karma Jasmine 2.8.0

My app is working fine but while i am trying to perform unit testing i am getting below mentioned error :
Error: StaticInjectorError(DynamicTestModule)[AppComponent ->
FinanceserviceService]: StaticInjectorError(Platform:
core)[AppComponent -> FinanceserviceService]:
NullInjectorError: No provider for FinanceserviceService!
My codes are given below :
financeservice.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import 'rxjs/add/operator/map';
#Injectable()
export class FinanceserviceService {
constructor(private _http: HttpClient) { }
finData() {
return this._http.get("./assets/data.json")
.map(result => result);
}
}
test.spec.ts
import { TestBed, inject,async,ComponentFixture } from '#angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '#angular/common/http/testing';
import { FinanceserviceService } from './financeservice.service';
import { AppComponent } from './XXXX.component';
import { SliderModule } from 'angular-image-slider';
import { CUSTOM_ELEMENTS_SCHEMA,NO_ERRORS_SCHEMA } from '#angular/core';
import 'rxjs/add/operator/map';
describe('FinanceserviceService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [FinanceserviceService],
schemas: [
CUSTOM_ELEMENTS_SCHEMA,
NO_ERRORS_SCHEMA
]
});
});
it(`should create`, async(inject([HttpTestingController, FinanceserviceService],
(httpClient: HttpTestingController, financeservice: FinanceserviceService) => {
expect(financeservice).toBeTruthy();
})));
});
*.component.ts
import { Component } from '#angular/core';
import { FinanceserviceService } from './financeservice.service';
import { Chart } from 'chart.js';
constructor(private _fin: FinanceserviceService){
}
ngOnInit() {
this._fin.finData()
.subscribe(res => {
let Fmax = res['list'].map(res => res.main.temp_max);
let Fmin = res['list'].map(res => res.main.temp_min);
let alldates = res['list'].map(res => res.dt)
let FDates = []
alldates.forEach((res) => {
let jsdate = new Date(res * 1000)
FDates.push(jsdate.toLocaleTimeString('en', { year: 'numeric', month: 'short', day: 'numeric' }))
})
this.chart=new Chart('canvas',{
type: 'line',
data: {
labels: FDates,
datasets: [
{
data: Fmax,
borderColor: "#3cba9f",
fill: false
},
{
data: Fmin,
borderColor: "#ffcc00",
fill: false
},
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
})
})
}
*.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { HttpClientModule } from '#angular/common/http';
import { FinanceserviceService } from './financeservice.service';
import { NgModule,CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { AppComponent } from './XXX.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { SliderModule } from 'angular-image-slider';
import { CommonModule } from '#angular/common';
import { NO_ERRORS_SCHEMA } from '#angular/core';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
SliderModule,
],
schemas: [NO_ERRORS_SCHEMA],
providers: [FinanceserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
Kindly help

The pipe 'limitTo' could not be found issue in angular 5

I created a custom pipe module and imported it in my custom module,but it's not working
limit.pipe
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({
name: 'limitTo'
})
export class RcycLimitPipe implements PipeTransform {
transform(value: any, args?: any): any {
let limit = args ? parseInt(args, 10) : 10;
let trail = '...';
return value.length > limit ? value.substring(0, limit) + trail : value;
}
}
limit.pipe.module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RcycLimitPipe } from './rcyc-limit.pipe';
#NgModule({
imports: [
CommonModule
],
declarations: [
RcycLimitPipe
],
exports: [
RcycLimitPipe
]
})
export class RcycLimitPipeModule { }
then I imported it in my custom modules.
import { NgModule } from '#angular/core';
import { ChannelsComponent } from './rcyc-channels.component';
import { routing } from './rcyc-channels.routing';
import { CommonModule } from '#angular/common';
import { NgxCarouselModule } from "ngx-carousel";
import { RcycChannelsService } from "./rcyc-channels.service";
import { RcycLimitPipeModule } from "../../rcyc-pipes/rcyc-limit/rcyc-limit.module";
import { RcycDefaultImagePipeModule } from '../../rcyc-pipes/rcyc-default-image/rcyc-default-image.module';
#NgModule({
imports: [routing,CommonModule,NgxCarouselModule,RcycLimitPipeModule,RcycDefaultImagePipeModule],
declarations: [ChannelsComponent],
providers: [RcycChannelsService]
})
export class ChannelsModule {}
but it still showing an error by telling that 'the limit and the 'defaultimage' could not be found.
this is my error
what the issue is here?please help me
Do you really need a separate module for your pipe? After all, you are really just importing NgModule, CommonModule (which you also import in your main module) and RcycLimitPipe.
You could simply remove limit.pipe.module altogether, import RcycLimitPipe in your main module and add it to its declarations.