ngOninit not getting called angular 2 express - node.js

I don't know but, Some weird thing happening up, I referred the default code provided on "Angular.io" to perform angular service calls, but some how ngOninit method is not getting called.
I have also implemented component from OnInit. and added #Injectable to user.services.ts. But still don't know where I am getting wrong.
Below is the code for the reference.
app.component.ts
//app.components.ts
import { Component } from '#angular/core';
import {User} from './user';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'Society CRM';
}
user.ts
export class User
{
_id : string;
name: string;
email: string;
username: string;
password: string;
phone: string;
address: string;
role: string;
created_date: string;
}
user-list.component.ts
import {Component,OnInit} from '#angular/core';
import {User} from './user';
import {UserService} from './user.service';
import { Headers, RequestOptions } from '#angular/http';
#Component({
selector:'user-list',
templateUrl:'./user-list.html',
providers: [ UserService ]
})
export class UserListComponent implements OnInit{
errorMessage: string;
users: User[];
mode = 'Observable';
constructor (private userService: UserService) {};
ngOnInit() {
this.getUsersList();
alert('here');
}
getUsersList() {
return this.userService.getUsersList()
.subscribe(
users => this.users = users,
error => this.errorMessage = <any>error);
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import { UserListComponent } from './user-list.component';
import { UserService } from './user.service';
import { FormsModule } from '#angular/forms'; // <-- NgModel lives here
#NgModule({
declarations: [
AppComponent,
UserListComponent
],
imports: [
BrowserModule,
HttpModule,
FormsModule
],
providers: [UserService],
bootstrap: [AppComponent]
})
export class AppModule { }
user.service.ts
import {Injectable} from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import {User} from './user';
import { Headers, RequestOptions } from '#angular/http';
#Injectable()
export class UserService
{
constructor (private http:Http){}
private api_url = "http://localhost:3000/api/";
getUsersList() : Observable<User[]>
{
let headers = new Headers();
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('Access-Control-Allow-Methods', 'GET');
headers.append('Access-Control-Allow-Headers', 'Content-Type');
let options = new RequestOptions({headers: headers});
return this.http.get(this.api_url+'getUsersList',options)
.map(this.extractData)
.catch(this.handleError);
}
private extractData(res: Response) {
let body = res.json();
return body.data || {};
}
private handleError(error: Response | any) {
// In a real world app, you might use a remote logging infrastructure
let errMsg: string;
if (error instanceof Response) {
const body = error.json() || '';
const err = body.error || JSON.stringify(body);
errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
} else {
errMsg = error.message ? error.message : error.toString();
}
console.error(errMsg);
return Observable.throw(errMsg);
}
}
I don't know what exactly is happening with the above code, no error being shown on firebug console or browser console. Any help would be thankful

Change your app.component.html code by adding this:
<user-list></user-list>
OnInit isn't called because you don't use user-list.component.

Check that you indeed use the component...
For example is the tag <user-list></user-list> defined somewhere in your html?

Related

Nest.JS - Global authentication guard

I want to implement a global authentication guard in My NestJS application that will simply read certain headers and assign user values based on those headers, for every request that comes in.
I implemented this simple logic and registered my global guard in my main module, however for some reason all my requests fail with '401 Unauthorized'. I tried to place log messages inside internal.strategy.ts, however I don't see them getting called.
Any idea why the strategy is not called?
This is my main.ts:
import { NestFactory, Reflector } from '#nestjs/core';
import * as logging from './logging';
import { AppModule } from './app.module';
import config from './config';
import { LocalAuthGuard } from './auth/guards/local-auth.guard';
async function bootstrap(port: string | number) {
const app = await NestFactory.create(AppModule);
app.useGlobalGuards(new LocalAuthGuard())
await app.listen(port, '0.0.0.0');
logging.logger.info(`Listening on 0.0.0.0:${port}`);
}
bootstrap(config.port);
This is my auth.module.ts:
import { Module } from '#nestjs/common';
import { PassportModule } from '#nestjs/passport';
import { AuthService } from './auth.service';
import { InternalStrategy } from './stategies/internal.strategy';
#Module({
imports: [PassportModule],
providers: [AuthService, InternalStrategy ]
})
export class AuthModule {}
This is my auth.service.ts:
import { Injectable } from '#nestjs/common';
import { Role } from 'src/workspaces/interfaces/models';
#Injectable()
export class AuthService {
validateUser(headers: Headers): any {
const workspaceId = headers['workspace-id'];
const workspaceRole = Role[headers['workspace-role']];
return {
workspaceId: workspaceId,
workspaceRole: workspaceRole
}
}
}
This is my internal.strategy.ts:
import { Strategy } from 'passport-local';
import { PassportStrategy } from '#nestjs/passport';
import { Injectable, UnauthorizedException } from '#nestjs/common';
import { AuthService } from '../auth.service';
#Injectable()
export class InternalStrategy extends PassportStrategy(Strategy, 'internal') {
constructor(private authService: AuthService) {
super({ passReqToCallback: true });
}
async validate(req: Request): Promise<any> {
console.log('Validate internal strategy')
const user = await this.authService.validateUser(req.headers);
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
Here is my local-auth.guard.ts:
import { Injectable } from '#nestjs/common';
import { AuthGuard } from '#nestjs/passport';
#Injectable()
export class LocalAuthGuard extends AuthGuard('internal') {}

JW Angular Pagination Doesn't Work if used in Feature Module

I'm using Angular 10 and the JW Angular Pagination module works fine if I import it into app.module.ts and then use it in a view that uses the app.component.ts component. However, when I try to import it into a custom feature module and use a component that imports the feature module, the pagination element does not display in the view template. It seems that Angular cannot see the pagination module.
App.module.ts
import { NgModule, Component, OnInit } from '#angular/core';
import { CoreModule } from "./core/core.module"
import { MessageModule } from "./messages/message.module";
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import * as $ from 'jquery';
import { BrowserModule } from '#angular/platform-browser';
import { AuthService } from "./model/auth.service"
import { JwPaginationModule } from 'jw-angular-pagination';
#NgModule({
imports: [AppRoutingModule, MessageModule, CoreModule, BrowserModule, JwPaginationModule],
declarations: [AppComponent,],
providers: [AuthService],
bootstrap: [AppComponent]
})
export class AppModule {
}
Core.module.ts
import { NgModule } from "#angular/core";
import { ModelModule } from "../model/model.module";
import { FormsFeatureModule } from "../view/forms.module";
import { ViewFeatureModule } from "../view/view.module";
import { routing } from "../app.routing";
import { MessageModule } from "../messages/message.module";
import { MessageService } from "../messages/message.service";
import { Message } from "../messages/message.model";
import { AuthService } from "../model/auth.service";
import { EncrDecrService } from '../utils/EncrDecr.service';
import { CommonModule } from '#angular/common';
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
#NgModule({
imports: [ModelModule, MessageModule, routing, FormsFeatureModule, ViewFeatureModule, CommonModule],
declarations: [],
exports: [ModelModule, FormsFeatureModule, ViewFeatureModule, MessageModule ],
providers: [AuthService, EncrDecrService],
})
export class CoreModule {
}
Forms.module.ts
import { NgModule } from "#angular/core";
import { FormsModule, Validators, FormGroup, FormBuilder, NgForm } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule } from '#angular/router';
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
import { ActivatedRoute, Router } from "#angular/router";
import { AuthService } from "../model/auth.service";
import { JwPaginationModule } from 'jw-angular-pagination';
#NgModule({
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule, JwPaginationModule],
declarations: [],
exports: [FormsModule, ReactiveFormsModule, RouterModule, JwPaginationModule],
providers: [AuthService],
})
export class FormsFeatureModule {
constructor(private router: Router) { }
View.module.ts
import { RecipeViewComponent } from "../view/recipeView.component";
import { NgModule } from "#angular/core";
import { FormsModule } from '#angular/forms';
import { ReactiveFormsModule } from '#angular/forms';
import { BrowserModule } from '#angular/platform-browser';
import { RouterModule } from '#angular/router';
import { HomePageComponent } from "./homePage.component";
import { AdminComponent } from "../admin/admin.component";
import { AuthService } from "../model/auth.service";
//import { NotFoundComponent } from "./notFound.component";
//import { UnsavedGuard } from './unsaved.guard';
#NgModule({
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule],
declarations: [RecipeViewComponent, HomePageComponent, AdminComponent],
exports: [RecipeViewComponent, HomePageComponent,AdminComponent, RouterModule],
providers: [AuthService],
})
export class ViewFeatureModule { }
admin.component.ts
import { Component, Inject, DoCheck, ChangeDetectorRef, OnInit } from "#angular/core";
import { ActivatedRoute, Router } from "#angular/router";
import { ModelRepo } from "../model/repository.model";
import { Category } from "../model/category.model";
import { Ingredient } from "../model/ingredient.model";
import { RecipeBook } from "../model/recipeBook.model";
import { User } from "../model/user.model";
import { FormsFeatureModule } from "../view/forms.module"
import { ViewChild, ElementRef } from '#angular/core';
import { EncrDecrService } from '../utils/EncrDecr.service';
import { AppComponent } from '../app.component'
import { Observable, throwError } from "rxjs";
//import { MODES, SharedState, SHARED_STATE } from "./sharedState.model";
//import { Observer} from "rxjs"
#Component(
{
selector: "admin",
templateUrl: "admin.component.html"
}
)
export class AdminComponent implements OnInit {
ModNewCategory = new Category(0,"");
ModNewIngredient = new Ingredient(0,"");
ModNewRecipeBook = new RecipeBook();
selectedConfig = "categories"; //initilze for first page load
selectedCategoryOperation = "addCategory"; //initilze for first page load
selectedIngredientOperation = "addIngredient"; //initilze for first page load
selectedUserOperation = "addUser"; //initilze for first page load
userRoles = new Array<string>("visitor", "member", "administrator");
searchRole = "";
id;
mode;
operation;
defaultObject = new Object();
public pageOfItems: Array<any>;
public items = [];
constructor(public dataRepo: ModelRepo, private EncrDecr: EncrDecrService, private appComponent:AppComponent, activeRoute: ActivatedRoute, public router: Router, public fieldValidator: FormsFeatureModule) {
activeRoute.params.subscribe(params => {
this.id = params["id"];
this.mode = params["mode"];
this.operation = params["operation"]
if (this.operation != null && this.mode != null) {
this.modifyItem(this.id, this.operation);
}
}
)
}
ngOnInit() {
// an example array of 150 items to be paged
// this.items = this.dataRepo.users;
this.items = Array(150).fill(0).map((x, i) => ({ id: (i + 1), name: `Item ${i + 1}` }));
}
onChangePage(pageOfItems: Array<any>) {
// update current page of items
alert('onChangePage got called');
this.pageOfItems = pageOfItems;
}
admin.component.html
<div class="card text-center m-3">
<h3 class="card-header">Angular Pagination Example</h3>
<div class="card-body">
<div *ngFor="let item of pageOfItems">{{item.name}}</div>
</div>
<div class="card-footer pb-0 pt-3">
<jw-pagination [items]="items" (changePage)="onChangePage($event)"></jw-pagination>
</div>
</div>
The Problem
You are using Angular10...
Have a look at the below statement Ivy is not complaining about unknown element inside ng-template
#36171
This is due to an architectural change in Ivy. In the previous compiler (ViewEngine), the check for unknown elements would occur during parsing of the template. In Ivy, templates are parsed independently from the corresponding NgModule, so information on components/directives in scope is not available.
Instead, checking of elements is pushed into the template type checking phase and it's currently affected by the type checker's configuration. With fullTemplateTypeCheck set to true however, it should descend into templates to check them (when it's false, it won't for backwards compatibility reasons). This conflicts however with your statement here:
The issue can only be found in runtime (no component being rendered) or with fullTemplateTypeCheck: true.
Consider the imports array in the module you are declaring AdminComponent
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule],
This module does not have any idea about a JwPaginationModule
Solution
The simplest solution is to simply add JwPaginationModule to this array
imports: [FormsModule, ReactiveFormsModule, BrowserModule, RouterModule, JwPaginationModule],
Now the module will know about this component and render correctly.

Logout button functionality in mean stack ,how to make the session expire?

i have been working on a project as intern and is new to mean stack
this is the issue i am facing ,
i have been asked to create a login page that is done , but the catch is the login is authenticated by the company side . So basically in my login component the following logic is what i have implemented.
login.component.ts file’s component goes like the following
onSubmit(event) {
event.preventDefault()
console.log('value',this.loginForm.value)
if(this.errorMail.length === 0) {
this.loginService.login(this.loginForm.value).subscribe((res:any) => {
console.log('login response', res)
if(res.auth.success === true) {
localStorage.setItem('auth', JSON.stringify(res.auth))
this.loginService.loggedIn$.next(res.auth)
this.router.navigateByUrl('/search/list')
} else {
this.errorMail='Email or password is not valid'
}
})
}
the following is login.service.ts
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http'
import { BehaviorSubject } from 'rxjs';
interface LoginResponse {
success: boolean
}
#Injectable({
providedIn: 'root'
})
export class LoginService {
constructor(private http: HttpClient) { }
loggedIn$ = new BehaviorSubject(null)
login(creds) {
// console.log('creds',creds)
return this.http.post<LoginResponse>('url-of-company', {creds})
}
and in my header component where i have the logout button :
the content of header.component.ts ;
import { Router } from '#angular/router';
import { Component, OnInit } from '#angular/core';
import { HeaderService } from './header.service';
#Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
constructor(public authService: HeaderService,public router:Router) { }
onLogout(){
this.authService.logout();
this.router.navigateByUrl('/');
}
the authService in above code is imported from header.service.ts and the header.service.ts goes like;
import { LoginService } from './../../login/login.service';
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http'
import { Router } from '#angular/router';
interface LoginResponse {
success: boolean
}
export class HeaderService{
constructor(private router: Router,private http: HttpClient,private user:LoginService) {}
logout() {
this.http.delete<LoginResponse>('url-of-comapy');
this.router.navigate(['/']);
}
Basically i am trying to delete the authentication creds which i am getting from the url-of-company and is redirecting it to the login page
please help me with what is wrong an where i should do the correction and what to do for logout in my scenario .
I think what you need to do is delete the creds from localStorage not from the database which is what you are trying to do in the code above in logout() function.
You do not need the logout() function in authService and change your onLogout() function in header.component.ts to this:
onLogout(){
localStorage.removeItem('auth');
this.router.navigateByUrl('/login');
}

How to use socket.io in angular with node.js?

Clientside I used Angular 6 and Serverside i used node.js.
Here in angular 6 console it print message and
socket.io id({message: "Hello World", id: "6An-ctwlwbZZWrfMAAAB"})
after using below code.
this code is right or any change in this code bcoz I am not sure about this code kindly help to make correct this.
and another query is I have more than 15 components in my project so how to make common use this socket.io for all components or I have to import this app.component.ts code in all another component.
app.js(serverside)
after installing (npm i socket.io)
const express = require('express');
var app = express();
const http = require('http');
const socketIo = require('socket.io');
const server = http.Server(app);
const io = socketIo(server);
server.listen(3000,function(req,res){
console.log("listen at 3000!");
});
io.on('connection',(socket) => {
socket.emit('hello',{
message : 'Hello World',id: socket.id
})
});
app.component.ts(clientside)
after installing (npm i socket.io)
import * as socketIo from 'socket.io-client';
export class AppComponent implements OnInit {
ngOnInit(){
const socket = socketIo('http://localhost:3000/');
socket.on('hello',(data) => console.log(data));
}
}
}
The one way to achieve this mechanism is using ngx-socket-io, connect your node server at the module level or root level i have implemented like below
app.module.ts code
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { SocketIoModule, SocketIoConfig } from 'ngx-socket-io';
import { AppComponent } from './app.component';
const config: SocketIoConfig = { url: 'http://192.168.1.187:9301', options: {} };
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
SocketIoModule.forRoot(config),
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
create one service which handles your incoming and outgoing traffic.
import { Injectable } from '#angular/core';
import { Socket } from 'ngx-socket-io';
#Injectable({
providedIn: 'root'
})
export class SocketService {
constructor(public socket: Socket) { }
getMessage() {
return this.socket
.fromEvent<any>('msg')
.map(data => data.msg);
}
sendMessage(msg: string) {
this.socket.emit('msg', msg);
}
}
Update your code in your component file
export class AppComponent implements OnInit {
constructor(private socketService: SocketService) {}
title = 'app';
incomingmsg = [];
msg = 'First Protocol';
ngOnInit() {
this.socketService
.getMessage()
.subscribe(msg => {
console.log('Incoming msg', msg);
});
this.sendMsg(this.msg);
}
sendMsg(msg) {
console.log('sdsd', msg);
this.socketService.sendMessage(msg);
}
}
Create Service and turn your socket data into Observable stream
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs/behaviorSubject';
import { Observer } from 'rxjs/Observer';
import { Observable } from 'rxjs/Observable';
import * as Rx from 'rxjs';
import * as io from 'socket.io-client';
#Injectable()
export class ChatService {
observable: Observable<string>;
socket;
constructor() {
this.socket = io('http://localhost:3000');
}
getData(): Observable<string> {
return this.observable = new Observable((observer) =>
this.socket.on('hello', (data) => observer.next(data))
);
}
// This one is for send data from angular to node
pushData(e) {
this.socket.emit('hello', e);
}
}
Then Call from component
App.component.ts
import { Component } from '#angular/core';
import { ChatService } from './common/chat.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title;
chat;
constructor(private cService: ChatService) {
this.cService.getData().subscribe(data => console.log(data));
}
onClick(e: string) {
this.cService.pushData(e);
this.chat = '';
}
}
You can create a service for working with a socket. E.g (of course this is a very simple example):
/* e.g app/shared/io/io.service.ts */
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs/Observable';
import * as socketIo from 'socket.io-client';
const SERVER_URL = '/';
/** Your events enum */
export enum IOEventName {
EVENT_NAME_1 = "EVENT_NAME_1",
EVENT_NAME_2 = "EVENT_NAME_2",
...
}
/** Interfaces for your event messages */
export interface IEventName1Message {
propOne: number,
propTwo: string,
...
}
export interface IEventName2Message {
propOne: Date,
propTwo: Boolean,
...
}
...
#Injectable()
export class SocketService {
private socket: SocketIOClient.Socket;
public initSocket(): void {
this.socket = socketIo(SERVER_URL);
}
public onEvent<T>(event: IOEventName): Observable<T | Array<T>> {
return new Observable<T>(observer => {
this.socket.on(event, (data: T) => observer.next(data));
});
}
public destroy() {
if (this.socket) {
this.socket.removeAllListeners();
this.socket.close();
this.socket = undefined;
}
}
}
And use it in any components:
import { SocketService, IOEventName, IEventName1Message, IEventName2Message }
from 'app/shared/io/io.service';
export class AppComponent implements OnInit, OnDestroy {
constructor(private socketService: SocketService) { }
ngOnInit() {
this.socketService.initSocket();
this.socketService
.onEvent<IEventName1Message>(IOEventName.EVENT_NAME_1)
.subscribe(data => { /* message received */ });
this.socketService
.onEvent<IEventName2Message>(IOEventName.EVENT_NAME_2)
.subscribe(data => { /* message received */ });
}
ngOnDestroy() {
this.socketService.destroy();
}
}

Angular (2+): HttpClient, subscribe, xhr

Situation:
I'm using Angular CLI. And I'm trying to receive data from the server side (node.js, express). I created new component card-object. I copied this code from the example on this page: https://angular.io/guide/http
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { HttpClientModule } from '#angular/common/http';
import { MatGridListModule, MatCardModule } from '#angular/material';
import { AppComponent } from './app.component';
import { CardObjectComponent } from './card-object/card-object.component';
#NgModule({
declarations: [
AppComponent,
CardObjectComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
HttpClientModule,
MatGridListModule,
MatCardModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html:
<app-card-object></app-card-object>
card-object.component.ts:
import { Component, OnInit, ViewEncapsulation } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-card-object',
templateUrl: './card-object.component.html',
styleUrls: ['./card-object.component.css'],
encapsulation: ViewEncapsulation.None
})
export class CardObjectComponent implements OnInit {
results: string[];
constructor(private http: HttpClient) {}
ngOnInit(): void {
this.http.get('http://localhost:3000/?cll=bjc').subscribe(data => {
this.results = data['results'];
});
}
}
card-object.component.html:
<p>{{results[0]}}</p>
<p>some text</p>
node.js:
app.get('/', (req, res) => {
var reqCard = {
results: ['text 1', 'text 2']
};
res.json(reqCard);
});
Problem:
I see that json data I receive successfully (I can see them in google DevTool => Network => XHR). But everything that I see in my angular app is 'some text'. And I see ERROR TypeError: Cannot read property '0' of undefined in my DevTool console.
Question:
Where is a mistake? What have I missed?
Initialize your array so that it has a value before the async call completes:
ngOnInit(): void {
this.results = []
this.http.get('http://localhost:3000/?cll=bjc').subscribe(data => {
this.results = data['results'];
});
}
Bind if results has data:
<p>{{results.length > 0 ? results[0]: ''}}</p>
<p>some text</p>

Resources