Issue
I have 2 Services that are located in /services, AccountService and AuthenticationService. I also have 2 pages: accounts.page and add-accounts.page that are located in /accounts and add-accounts.page is located in /accounts/add-accounts. I use the AccountService in both accounts.page and add-accounts.page which loads the accounts from a local json and stores them in Ionic/Storage. So the plan is to use the Service for getting the accounts from the storage and adding new accounts. I have a ReplaySubject in the service to detect new changes which I want to use in the accounts html page to display an accounts array. I am using Ionic 4 with Angular version 7
After tinkering around I found out that the service is getting 2 instances so I don't add new changes to the ReplaySubject I originally started with. I found this out by adding a console.log to the constructor of my service and looking in the console I found 2 instances of the same console.log after going from the accounts page to the add-accounts page. So the changes I do to the accountService in add-accounts page are another instance and are not changed in the first one.
When I test this with my other Service (AuthenticationService) I do not get 2 console.log output in the console. I doubled checked the @Injectable decorators if they have the correct syntax for providedIn: 'root' and after testing the older angular method of removing the providedIn: 'root' part and importing the Service in app.module.ts and adding it in the providers array I get a NullInjectorError: No provider for AccoutService Error which I couldn't solve.
I tried creating a new service with ionic g service services/newService
and made a function to output some text. I also created a BehaviourSubject to see and track state changes. It looks like this:
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class NewAccoutService {
authenticationState = new BehaviorSubject(false);
constructor() {
this.authenticationState.next(true);
console.log('This text should only happen once');
}
consoleLog() {
console.log('did it work?');
}
}
What I also tried to do is create a new blank ionic project and created 2 pages and 2 services. In that project they behaved as they should be, only being created once.
After talking with my colleagues they suggested creating a new test project with the same file structure and copy/paste the code into the new project which would maybe solve the problem because of some files not being created probably. This however didn't work out so there might be something else wrong.
account.service.ts
Here is the relevant code for the AccountService
import { Injectable } from '@angular/core';
@Injectable(
{ providedIn: 'root' }
)
export class AccountService {
changed: ReplaySubject<Account[]> = new ReplaySubject(1);
constructor(
private http: HttpClient,
private storage: Storage
) {
console.log('Account Service constructor Text');
// some other code
}
}
account.page.ts
Here is the relevant code for the Account Page
import { AccountService } from '../services/account.service.js';
import { AuthenticationService } from '../services/authentication.service.js';
@Component({
selector: 'app-accounts',
templateUrl: './accounts.page.html',
styleUrls: ['./accounts.page.scss'],
})
export class AccountsPage implements OnInit,OnDestroy {
accounts: Account[] = [];
accountsLoaded = false;
subscription: any;
constructor(private http: HttpClient,
private accountService: AccountService,
private router: Router,
private authService: AuthenticationService,
private changeRef: ChangeDetectorRef,
private testService: NewAccoutService) {
}
ngOnInit() {
this.testService.authenticationState.next(false);
console.log('Test Service state: ', this.testService.authenticationState.value);
}
}
add-account.page.ts
Here is the relevant code for the Add-account Page
import { AccountService } from '../../services/account.service';
import { AuthenticationService } from '../../services/authentication.service';
@Component({
selector: 'app-add-accounts',
templateUrl: './add-accounts.page.html',
styleUrls: ['./add-accounts.page.scss'],
})
export class AddAccountsPage implements OnInit {
public account: FormGroup;
public currentSliderValue: number = 1;
constructor( private platform: Platform,
private changeRef: ChangeDetectorRef,
private router: Router,
private accountService: AccountService,
private authentication: AuthenticationService,
private testService: NewAccoutServiceService ) {
this.testService.authenticationState.next(false);
console.log('Test Service state: ', this.testService.authenticationState.value);
}
}
When I load the account page I expect to see the following:
Expected outcome: When I load accounts.page I want to see the console.log message. this.testService.authenticationState.value
is false
.
When I go from accounts.page to add-accounts the console.log from the AccountService should not be called again. this.testService.authenticationState.value
is true
.
Actual outcome: Loading into account.page I see the console.log message and this.testService.authenticationState.value
is false
. Loading from accounts.page to add-accounts.page I get another constructor console.log message also this.testService.authenticationState.value
is still false
I am running out of options to try since I am still new to Ionic and Angular. Every service should work as a singleton but it somehow doesn't work. Let me know if you need additional code to help me solve this issue.
Edit:
I have found the solution which is so stupid. VS Code generated at one point the imports for my services in accounts.page.ts and for some unknown reason it added .js
after the file location I mean look at this comparison.
import { AuthenticationService } from '../services/authentication.service';
import { AuthenticationService } from '../services/authentication.service.js';
Not one of 3 people looking at my code at work found this problem. Only today after another 3 hours of trying everything and looking at the code very carefully my colleague and me thought about an import issue when it suddenly came to me "Why is there a .js in that import, that's not right".
Solution
I found the solution
For anyone somehow encountering this error. In my imports which VS Code generated there was a .js extension after the file location.
Before:
import { AuthenticationService } from '../services/authentication.service.js';
After:
import { AuthenticationService } from '../services/authentication.service';
After removing this extension it works as it should be. I don't know why VS Code only did it in my accounts.page.ts only that one time but that's another problem which doesn't occur anymore.
Answered By - PatrickJung
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.