Call Service inside ngdobootstrap - javascript

I am creating application using angular and calling api call inside the ngdobootrap method. I am getting error while injecting the service inside bootstrap:
export class AppModule {
constructor(private upgrade: UpgradeModule, private router: Router, private location: Location,private services : someservice) { }
ngDoBootstrap(moduleRef) {
this.getdata()
}
getdata() {
this.services.data().subscribe((res: any) => {
console.log(res)
}, error => {
})
}
Error:
zone.js:682 Unhandled Promise rejection: Trying to get the AngularJS injector before it being set. ; Zone: <root> ; Task: Promise.then ; Value: Error: Trying to get the AngularJS injector before it being set.
at injectorFactory (vendor.js:148805:15)

Add the forwardRef to the service in the constructor,
#Inject(forwardRef(() => 'someservice')) private services : someservice
There is more detail here

Related

NestJS - current auth user but not via decorator

I create belowed decorator to get current logged in to the system user,
export const CurrentUser = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
return request.user;
},
);
but I do not want to use this because i need to use in any of my controller
which is a bit troublesome for me because some functions are optional, i.e. both for the logged in user and the non logged in user,
so, how can I get current logged in user in my service in functions when i want to get current user instead of all via decorator in controller?
thanks for any help
You'd have to make a custom provider and inject the request into it. Something like this
{
provider: 'CURRENT_USER',
inject: [REQUEST],
useFactory: (req: Request) => {
return req.user;
},
scope: Scope.REQUEST,
}
(REQUEST is injected from #nestjs/core)
Then the user can be injected into the service with #Inject('CURRENT_USER'). Keep in mind, this will make the service REQUEST scoped, and by scope hierarchy it will make whatever you inject the service into REQUEST scoped.
Edit 2/15/21
An example of this module could look something like this:
#Module({
providers: [{
provider: 'CURRENT_USER',
inject: [REQUEST],
useFactory: (req: Request) => {
return req.user;
},
scope: Scope.REQUEST,
}],
exports: ['CURRENT_USER'],
})
export class CurrentUserModule {}
And now in whatever module that has the service that needs the current user you do
#Module({
imports: [CurrentUserModule],
providers: [ServiceThatNeedsUser],
})
export class ModuleThatNeedsUser {}
and in the service:
#Injectable()
export class ServiceThatNeedsUser {
constructor(#Inject('CURRENT_USER') private readonly user: UserType) {}
// rest of class implementation
}

How to write Test cases for below angular method

I have created a component that opens my custom type dialog, I just want to create Jasmine unit test cases for this method.
export class OpenPopUpComponent implements OnInit {
constructor(public dialog:NewCustomDialog) {}
ngOnInit() {
}
openModel(){
this.dialog.open(NewComponent,<NewCustomDialogConfig>{
size: 'double',
data: {
title: 'New Dialog'
}
});
}
}
You will not test the dialog itself. What you need to do is to mock the NewCustomDialog and provide it as injected.
In your spec.ts
beforeEach(() => {
const spy = jasmine.createSpyObj('NewCustomDialog', ['open']);
TestBed.configureTestingModule({
// Provide (spy) dependency
providers: [
{ provide: NewCustomDialog, useValue: {newCustomDialogSpy} }
]
});
// Inject both the service-to-test and its (spy) dependency
masterService = TestBed.get(MasterService);
valueServiceSpy = TestBed.get(ValueService);
});
Then you can check that the spy has been called with parameters (the ones you expect).
The intension of the unit test is to test the feature of component itself and not to start testing the features which is outside the scope of component which is to be tested. So,
you do not need to test dialog.open as this should be tested in unit test of NewCustomDialog itself.
start by creating a Stub which you can use as a placeholder for NewCustomDialog, such as
export class NewCustomDialogStub{
open(){ return null; }
close(){ return null; }
// and similar dummy methods which is required by "OpenPopUpComponent"
}
Inject this stub as useClass in providers as below:
export class NewCustomDialogStub{
open(){ return null; }
close(){ return null; }
// and similar dummy methods which is required by "OpenPopUpComponent"
}
describe('OpenPopUpComponent', () => {
let component: OpenPopUpComponent;
let fixture: ComponentFixture<OpenPopUpComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
declaration: [OpenPopUpComponent],
providers: [
{ provide: NewCustomDialog, useClass: NewCustomDialogStub }
]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(OpenPopUpComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be defined',()=>{
expect(component).toBeDefined();
})
it('should call "open" method of dialog on calling openModel() ',()=>{
spyon(component.dialog,'open').and.callThrough();
component.openModel();
expect(component.dialog.open).toHaveBeenCalled();
})
})
This is very basic testing but if you want to know more about writing tests , you can refer to this series of articles where I have covered almost all basic testing scenarios . Check the bottom of article for all links. The one which I used here is this one

Not able to find route custom data in angular 6 in app component

I have an angular application and added custom data to the route given as
{ path: 'profile', component: ProfileComponent, data: {title: 'example'} }
and in app.component.ts file I have the following code as
private route: ActivatedRoute
console.log('route snapshot', this.route.firstChild.data._value.pageType );
the error i am getting is
ERROR in src/app/app.component.ts(71,64): error TS2339: Property '_value' does not exist on type 'Observable<Data>'.
can anyone tell me how to access data of route in app.component.ts
Update
You will need to subscribe to the router events in the AppComponent and get the params from it:
constructor(private router: Router, route: ActivatedRoute) { }
ngOnInit() {
this.router.events.subscribe(event => {
if(event instanceof NavigationEnd){
console.log(this.route.root.firstChild.snapshot.data['title']);
}
});
}
If you want it only for that path, you can add one more condition
if(event instanceof NavigationEnd && event.url === '/profile')
Old Answer
You will need to access the snapshot to get the data params
this.route.snapshot.data['title'];

Accessing custom service from event

I'm attempting to access a custom service from a custom event yet wheneven the event is fired the service reference is null
#Component({
selector: "my-component",
template: mySource,
legacy: { transclude: true }
})
export class myComponent {
constructor(
#Inject("$scope") private $scope: ng.IScope,
private myService: MyService) {
$scope.$on('$routeChangeSuccess', function (event) {
this.myService.myFunction();
});
}
});
}
when myService is referenced the following error is shown:
Cannot read property 'myService' of null
The solution is not to refer to myService from within myComponent prepended with
this.myService
but instead use
myService.myFunction()

How do I make services available outside of constructor in angular?

I have the following problem. When I have a class in ionic with angular I can access angular services in the constructor after injecting them:
export class HomeController {
static $inject = [
'$scope',
'$state'
];
constructor(
public $scope : any,
public $state : any
) {
this.$state.go('test');
this.$scope.changeController = this.changeController;
}
changeController() {
console.log("change controller");
};
}
However when I change it to the change controller function, it doesn't work
export class HomeController {
static $inject = [
'$scope',
'$state'
];
constructor(
public $scope : any,
public $state : any
) {
this.$scope.changeController = this.changeController;
}
changeController() {
console.log("change controller");
this.$state.go('test'); // Fails here
};
}
This is the error:
Error: undefined is not an object (evaluating 'this.$state.go')
What can I do?
On top of that, is it correct add the changeController function to the scope or is there an easier method to make it available to a template?
Thx in advance
In your case the value of this is incorrect which is a very common issue due to misunderstanding of ES6 classes. Try using lambda to have lexical scoping:
changeController = () => {
console.log("change controller");
this.$state.go('test'); // Fails here
};

Categories