I want to create an instance of this class which has arguments in its constructor as follows? - constructor

export class AuthService {
constructor(
private readonly usersService: UsersService,
#InjectModel('User') private readonly userModel: PassportLocalModel<IUser>,
) {}
async register(user: CreateUserDto) {
let status: RegistrationStatus = {
success: true,
message: 'user registerd',
};
await this.userModel.register(
new this.userModel({
username: user.email,
firstName: user.firstName,
lastName: user.lastName,
}),
user.password,
err => {
if (err) {
console.log(err);
status = { success: false, message: err };
}
},
);
return status;
}
}
I want to create an instance of this class but I am not able to figure out how to pass the arguments. How to handle the arguments for passport local model containing Iuser?

Looks like you lack on comprehension of the Dependency Injection of NestJS.
You should never instantiate a Service, but import it in the constructor of other class in the same way you are doing it with the UsersService.
For example, having your AuthServiceannotated with #Service decorator:
#Service
export class AuthService { ... }
You can then use it, let's say, in your AuthController
#Controller()
export class AuthController{
constructor (private readonly authService: AuthService) {}
register(user: UserDTO): RegistrationStatus {
this.authService.register(user);
}
}
NestJS will handle the instantiation of the Service and all its dependencies.
Just remember to add the AuthService in the providers property of the AuthModule, and, if you are going to use outside this module, export it adding it to the exports property.
Is a good practice to specify return types in methods.

Related

Get titles from Wikipedia

I am kinda new to Angular.
I am trying to get 4 titles from Wikipedia API, but i can't figure up what's wrong in my code
this is the eample URL for 1 title
example URL = https://en.wikipedia.org/w/api.php?action=query&prop=pageprops&format=json&titles=Wilson_Lumpkin
model
IwikiItem.ts:
export interface IWikiItem {
batchcomplete?: string;
query?: Query;
}
export interface Query {
normalized?: Normalized[];
pages?: Pages;
}
export interface Normalized {
from?: string;
to?: string;
}
export interface Pages {
id?: The4101295;
}
export interface The4101295 {
pageid?: number;
ns?: number;
title?: string;
pageprops?: Pageprops;
}
export interface Pageprops {
defaultsort?: string;
page_image_free?: string;
wikibase_item?: string;
}
Component
private titles = [
'Wilson_Lumpkin',
'Robert Toombs',
'Saxby Chambliss',
'Wyche Fowler',
];
export class HomeComponent implements OnInit {
dataSource: MatTableDataSource<IWikiItem>;
constructor(private srv: SrvService) {
this.titles.forEach((name) => {
this.srv
.getWiki('action=query&prop=pageprops&format=json&titles=' + name)
.subscribe((data) => {
console.log(data.query),
(this.dataSource: new MatTableDataSource<IWikiItem[data]>);
(err) => {
console.log(err);
};
});
});
}
}
service
export class SrvService {
readonly base_url = 'https://en.wikipedia.org/w/api.php?';
getWiki(title: string) {
return this.http.get<IWikiItem>(this.base_url + title);
}
constructor(private http: HttpClient) {}
}
What's wrong here? i am, getting this error in console:
error msg
Edit 1
I am getting an error this.handle eror.
error
I guess Wikipedia APis does not support CORS. So instead of normal http request, you need t make a jsonp request.
For jsonp request you need to import module HttpClientJsonpModule in your application.
After that you can make the request like below.
Reference Link
getWiki(title: string) {
const url = this.base_url + title;
return this.http.jsonp(url, 'callback').pipe(
catchError(this.handleError) // then handle the error
);
}
callback(response) {
console.log("response", response);
}
handleError(error){
console.log(error);
}
Working sample Link

ERROR TypeError: Cannot read property 'projectName' of undefined

I cant figure it out where the problem is. This is my template:
<h1>Details for {{ project.projectName }} </h1>
<h6>Project Description: {{ project.description }}</h6>
<h6>Project Stage: {{ project.stage }}</h6>
<hr />
<app-employee-list></app-employee-list>
<app-tickets-list></app-tickets-list>
This is the service where i get a single project:
interface GetResponse {
_embedded: {
projects: Project[];
};
}
#Injectable({
providedIn: "root",
})
export class ProjectService {
private baseUrl = "http://localhost:8080/api/projects";
renderRoleAssignment$: Subject<boolean>;
constructor(private httpClient: HttpClient) {
this.renderRoleAssignment$ = new Subject<boolean>();
}
getProjectList(): Observable<Project[]> {
return this.httpClient
.get<GetResponse>(this.baseUrl)
.pipe(map((response) => response._embedded.projects));
}
getProject(id: number): Observable<Project> {
return this.httpClient.get<Project>(this.baseUrl + "/" + id);
}
}
This is the project class:
export class Project {
id: number
_links?: Links;
projectName: string;
description: string;
stage: string;
}
export class Links {
self: { href: string };
}
And this is my component:
export class ProjectDetailsComponent implements OnInit, OnDestroy {
project: Project;
getProjectSub: Subscription;
private baseUrl = "http://localhost:8080/api/projects/";
constructor(
private route: ActivatedRoute,
private projectService: ProjectService
) {
this.getProjectSub = new Subscription();
}
ngOnInit() {
this.projectService.renderRoleAssignment$.next(false);
this.listProject();
}
listProject() {
const projectId = this.route.snapshot.params["id"];
this.getProjectSub = this.projectService
.getProject(projectId)
.subscribe((data) => {
this.project = data;
console.log(this.project)
this.addIdToProject(projectId);
console.log(this.project.id)
});
}
addIdToProject(id: number) {
this.project.id = id;
console.log(this.project.id)
this.route.params.subscribe((params: Params) => {
this.project.id = id;
});
}
ngOnDestroy() {
this.getProjectSub.unsubscribe();
}
}
The stack trace of the error:
core.js:4196 ERROR TypeError: Cannot read property 'projectName' of undefined
at ProjectDetailsComponent_Template (template.html:1)
at executeTemplate (core.js:7446)
at refreshView (core.js:7315)
at refreshComponent (core.js:8453)
at refreshChildComponents (core.js:7108)
at refreshView (core.js:7365)
at refreshEmbeddedViews (core.js:8407)
at refreshView (core.js:7339)
at refreshComponent (core.js:8453)
at refreshChildComponents (core.js:7108)
{projectName: "Game App", description: "A simple game", stage: "Completed", _links: {…}}
1
1
So as you can see from the logs the project is there, the id that i add are defined.
But for some reason it cant find the project properties and display them.
Here is whats going on: You are declaring project: Project at the top. Your html is trying to read a property off of project it is not defined yet so thats why you get Cannot read property 'projectName' of undefined as that call is made in the NgOnInit and is async.
Here is how to fix it as long as your service call is returning the correct data: Short way: Initialize project at the top. Long way: It would be a good idea to make Project an interface and call it IProject then create a class called Product that implements IProject.
export interface IProject {
id?: number
_links?: Links;
projectName?: string;
description?: string;
stage?: string;
}
export class Project implements IProject {
constructor(
public id: number,
public _links?: Links,
public projectName?: string,
public description?: string,
public stage?: string,
){}
}
Then in your component html:
project: IProject = {};
and of course in your service:
getProject(id: number): Observable<IProject> {
return this.httpClient.get<IProject>(`${this.baseUrl}/${id}`);
}
finally in your html using the optional chaining operator:
<h1>Details for {{ project?.projectName }} </h1>
Generally speaking, we should be using optional chaining wherever possible. In this case, this would save you some trouble:
<h1>Details for {{ project?.projectName }} </h1>
or if it makes more sense
<h1 *ngIf="project?.projectName">Details for {{ project.projectName }} </h1>
This error is thrown because you have declared project variable, but initialised it asynchronously some time after angular tried to render the view.
The same of course is valid for the rest of your html, wherever you are trying to access an object property that might be null or undefined.

Object inside function not getting executed when calling function from another component

Apologies for not being able to title my question properly.
Let me explain my issue properly.
I have 2 Components say A and B.
In B I have a function saveIndCustData which emits and saves data.
export class CustomerformComponent implements OnInit {
#Output()
savedIndCustomer: EventEmitter<any> = new EventEmitter<any>();
saveIndCustData() {
const savedIndCustomer = {
prefix: this.prefix,
nameType: this.indCustNameType,
firstName: this.firstName,
middleNAme: this.middleName,
lastName: this.lastName,
gender: this.gender,
dateOfBirth: this.parseDate(this.dateOfBirth.toString()),
citizenship: this.citizenship
};
this.savedIndCustomer.emit(savedIndCustomer);
this.snackbar.open('Customer Info Saved,Click on Next', 'Close', {
duration: 5000
});
}
}
I am now calling the function from component A.
import { CustomerformComponent } from './forms/customerform/customerform.component';
constructor(private custComp: CustomerformComponent) {}
saveCustomerForm(): void {
this.custComp.saveIndCustData();
}
I emit the data into a service class
#Output()
savedIndCustomer: EventEmitter<any> = new EventEmitter<any>();
Service Class
public addDynamiIndCustomerComponent() {
const factory = this.factoryResolver.resolveComponentFactory(CustomerformComponent);
const component = factory.create(this.rootViewContainer.parentInjector);
component.instance.savedIndCustomer.subscribe(data => {
console.log(data);
// Insert Individual Customer Type
this.custFullDetails.customerType = 'individual';
this.custFullDetails.individualCustomer.dateOfBirth = data.dateOfBirth;
this.custFullDetails.individualCustomer.citizenship = data.citizenship;
this.custFullDetails.individualCustomer.gender = data.gender;
this.custFullDetails.individualCustomer.individualName.push({
prefix: data.prefix,
firstName: data.firstName,
middleName: data.middleName,
lastName: data.lastName,
agreementId: data.agreementId,
nameType: data.nameType
});
console.log(this.custFullDetails.individualCustomer);
});
this.rootViewContainer.insert(component.hostView);
}
My issue is if I invoke the saveIndCustData function from component B it pushes data into array const savedIndCustomer{ ... } and calls the service class.
However when I invoke the same function from component A it doesn't invoke the const savedIndCustomer{ ... } method inside saveIndCustData() function and service class method does not save data in array but it simply shows the snakbar.
What is the issue?
Suppose you put the component B inside the html of component A, so you should make a reference for the component B like this
A.component.html:
...
<B #bcmp></B>
...
and inject it in A.component.ts using #ViewChild like this
A.component.ts:
#Component({
selector: 'A',
templateUrl: './A.component.html',
styleUrls: ['./A.component.scss']
})
export class AComponent implements OnInit {
#ViewChild("bcmp") bcmp : B
ngOnInit(): void {
// by this way you can use any method existant in B component
this.bcmp.saveIndCustData();
}
}

Angular can't read value of 'undefined' - unable to read value of 'casestudy' in the setTitle() method?

This is my component:
export class CaseStudyDetailComponent implements OnInit {
casestudy: CaseStudy;
constructor ( private caseStudyService: CaseStudyService, private route: ActivatedRoute, public titleService: Title ) { }
ngOnInit() {
this.route.params.subscribe((params: { Handle: string }) => {
this.caseStudyService.getCaseStudy(params.Handle).subscribe(casestudy => this.casestudy = casestudy);
});
this.titleService.setTitle(this.casestudy.Handle);
}
}
This is the service it is calling:
getCaseStudy(Handle: string): Observable<CaseStudy> {
return this.http.get<CaseStudy>(`${environment.apiPath}/project/handle/${Handle}`);
}
I want to be able to access the value of 'casestudy' in the 'setTitle()' method. I might potentially just be misunderstanding expected behaviour or have my syntax wrong.
Let me know if more information is required.
Because your console.log gets excecuted before your subscribe can set the response in the caseStudy.
To fix this put the console.log method in the subscribe
this.caseStudyService.getCaseStudy().subscribe(caseStudy => {
... code
console.log(caseStudy);
});

Storing Objects inside Object in Arrays in Angular 2

I'm trying to store this data, given from a Wordpress Backend with HTTP Get Request in Ionic 2 (Angular 2).
I'm receiving this data structure,
Console Log of data response-
I'm trying to store this data like the menus (menu_1 and menu_2) in array of menus, the categories in array of categories, dishes in array of dishes...
How can I do that?
I don't want to show or iterate using Pipes, I only want to storage in Arrays to work easier with them.
My code at the moment is like:
home.ts:
I have a injectable class (Globals) to call the http get, but I do the subscribe in the getMenus function on my home.ts component:
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Globals } from '../../providers/globals';
#Component({
selector: 'page-home',
providers: [Globals],
templateUrl: 'home.html'
})
export class HomePage {
menus: any;
constructor(public navCtrl: NavController, public globals: Globals) {
this.getMenus();
}
getMenus() {
this.globals.getMenus().subscribe(
data => {
console.log(data);
this.menus = data;
},
err => { console.log(err) }
);
}
}
And I have created a class, called Menu, at the moment is very simple:
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/map';
#Injectable()
export class Menu {
name: any;
categories: any;
constructor() {
this.name = this.name;
this.categories = this.categories;
}
}
Where name is basic field of the object (key: name, value: "Today's menu" and categories is cat_1, cat_2 (two objects inside menu_1 object, which each contains more objects (dish_1, dish_2...).
My idea is create a class for every one of them, class Menu, class Category and class Dish. But I have any idea of how can I start store this objects in this classes. :S
Greetings!
The first thing to do is to create an interface for the data that you receive from the server, something like:
interface Dish {
Name: string;
Description: string;
Thumbnail: string;
}
interface Category {
[name: string]: Dish;
}
type ServerResponse = {
[name: string]: { [name: string]: Category; } & { name: string };
}
If you want to create classes from this data you can then:
class Menu {
name: string;
categories: { [name: string]: Category };
constructor(data: { [name: string]: Category; } & { name: string }) {
this.name = data.name;
this.categories = {};
Object.keys(data).forEach(name => {
if (name !== "name") {
this.categories[name] = new Category(data[name]);
}
});
}
}
(data: ServerResponse) => {
this.menus = {};
Object.keys(data).forEach(name => {
this.menus[name] = new Menu(data[name]);
});
}
You should also create the Category class and all, but that's the idea.
What are you trying to do ?
I think what you're trying to do is to normalize your data.
(Are you using a Redux pattern ? Maybe Ngrx ? If so, this is a great idea to normalize !)
Here's how a normalized state looks like : http://redux.js.org/docs/recipes/reducers/NormalizingStateShape.html
How should you do it ?
You can either do it by hand, which will become quite hard if you have many other requests to deal with, or you can describe your data in schema and use normalizr to do this job (normalizing data) for you.
If you don't know where to start. You can try this approach. First, create a model:
export class DummyModel {
menu: any;
cat: any;
dish: any;
...
//you can replace any with the type expected (string, number, etc)
}
In your component, you import your dummyModel and you set the data
import { DummyModel } from '../dummy.model';
/...
dummyModel: DummyModel = dummyData;
Also, consider #Nitzan Tomer advise, try to write your code and people here can help if you are facing an issue