getting query params from url Angular - node.js

I want to grab id from url http://localhost:4200/courses/5a0eb3d7f6b50c2589c34e57 so in my app.module.ts I have such route {path:'courses/:id', component:CourseComponent, canActivate:[AuthGuard]} and in my course.component.ts I have the following code :
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-course',
templateUrl: './course.component.html',
styleUrls: ['./course.component.css']
})
export class CourseComponent implements OnInit {
id: String;
constructor(private route: ActivatedRoute) { }
ngOnInit() {
this.id = this.route.snapshot.queryParams["id"];
console.log(this.id)
}
}
Actually in my developer console I can see following
And if I try to console.log(params) I get following

You should use rxjs.
this.route.params.pluck('id').subscribe(v => console.log(v));
Preferable, since .params might be depracated soon:
this.route.paramMap.subscribe(paramMap => paramMap.get('id'));
Everything is in documentation... https://angular.io/guide/router#parammap-api

This is a route param and you should be using the params property
this.id = this.route.snapshot.params["id"];

Related

JWT library error: Generic type 'ModuleWithProviders<T>' requires 1 type argument(s) in Angular 10

For an authentication project I am using:
Angular CLI: 11.0.4 for the frontend
Node: 10.19.0 for the backend
OS: linux x64
I receive the following error after ng serve and I am not sure why that is happening, the error seems to be in the library node_modules/angular2-jwt/angular2-jwt.d.ts and not in the code I wrote:
node_modules/angular2-jwt/angular2-jwt.d.ts:88:41 - error TS2314:
Generic type 'ModuleWithProviders' requires 1 type argument(s).
static forRoot(config: AuthConfig): ModuleWithProviders;
Also connected to that (so I believe the errors are concurrent or even, I am afraid, interchangeable), because it was shown as soon as the 'ModuleWithProviders<T>' error was shown, so I though it would make sense to show them both as they are linked together:
Error: node_modules/angular2-jwt/angular2-jwt.d.ts:1:77 - error
TS2307: Cannot find module '#angular/http' or its corresponding type
declarations.
1 import { Http, Request, RequestOptions, RequestOptionsArgs, Response
} from "#angular/http";
So the difficulty I have is also due to the fact that I am not sure which parts of the code are affected so I will put for the sake of completeness the app.module.ts and the files carrying the jwt include
app.module.ts:
import { ValidateService } from './services/validate.service';
import { FlashMessagesModule } from 'angular2-flash-messages';
import { HttpClientModule } from '#angular/common/http';
import { AuthService } from './services/auth.service';
import { AuthGuard } from './guards/auth.guards';
const appRoutes: Routes = [
{path:'', component: HomeComponent},
{path:'register', component: RegisterComponent},
{path:'login', component: LoginComponent},
{path:'dashboard', component: DashboardComponent, canActivate: [AuthGuard]},
{path:'profile', component: ProfileComponent, canActivate: [AuthGuard]},
]
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
LoginComponent,
RegisterComponent,
HomeComponent,
DashboardComponent,
ProfileComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
RouterModule.forRoot(appRoutes),
FlashMessagesModule.forRoot(),
HttpClientModule,
],
providers: [ValidateService, AuthService, AuthGuard],
bootstrap: [AppComponent]
})
export class AppModule { }
auth.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { map } from 'rxjs/operators';
import { tokenNotExpired } from 'angular2-jwt';
#Injectable({
providedIn: 'root'
})
export class AuthService {
authToken: any;
user: any;
constructor(private httpClient: HttpClient) { }
registerUser(user) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
return this.httpClient.post('http://localhost:3000/users/register', user, httpOptions);
}
authenticateUser(user) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
};
return this.httpClient.post('http://localhost:3000/users/authenticate', user, httpOptions);
}
getProfile() {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
Authorization: this.authToken,
})
};
this.loadToken();
return this.httpClient.get('http://localhost:3000/users/profile', httpOptions);
}
storeUserData(token, user) {
localStorage.setItem('id_token', token);
localStorage.setItem('user', JSON.stringify(user));
this.authToken = token;
this.user = user;
}
loadToken() {
const token = localStorage.getItem('id_token');
this.authToken = token;
}
loggedIn() {
return tokenNotExpired();
}
logout() {
this.authToken = null;
this.user = null;
localStorage.clear();
}
}
profile.components.ts
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../../services/auth.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
user: Object = {};
constructor(private authService: AuthService, private router: Router) { }
ngOnInit(): void {
this.authService.getProfile().subscribe(profile => {
this.user = profile;
},
err => {
console.log(err);
return false;
})
}
}
I did research on how to solve the problem and here is was I was able to find so far:
this post is very useful because it has my same exact problem.
The answer calls for a bug report repo that, however, does not provide any answer to that.
The answer that was provided suggests to insert the following code:
declare module "#angular/core" {
interface ModuleWithProviders<T = any> {
ngModule: Type<T>;
providers?: Provider[];
}
}
Unfortunately this was not an accepted answer and I am not sure where I can put this piece of code in any part of the app.module.ts I provided above.
I also studied this post which was also useful but did not use the suggestion above.
The strange fact I understand from the error is that it seems to come from the library itself and not from the code that I wrote.
Following this I proceeded with:
rm -rf all the node_modules
rm -rf the package jason file
clean the cache
npm install
But outcome is the same, I always receive the same error on the same library.
Please if anyone had the same problem can you share how it was solved and what should I do more to take care of that.
Insert this piece of code into the angular2-jwt.d.ts class and confirm the class change:
declare module "#angular/core" {
interface ModuleWithProviders<T = any> {
ngModule: Type<T>;
providers?: Provider[];
}
}
But you should use a newer library than this, like #auth0/angular-jwt
After installing this library, you must register its module in the class app.module.ts :
import {JwtModule} from '#auth0/angular-jwt'
imports: [
JwtModule.forRoot({
config: {
tokenGetter:() => {
return localStorage.getItem('access_token');
},
},
})
],
And then you can use it in your AuthService class:
import {JwtHelperService} from '#auth0/angular-jwt';
constructor(public jwtHelper: JwtHelperService) {
}
isAuthenticated(): boolean {
return !this.jwtHelper.isTokenExpired(this.token);
}
All this is explained in a short documentation with examples (https://www.npmjs.com/package/#auth0/angular-jwt), so don't be lazy to read it before using any library.

Angular 7 / Material DataTable not updating after any operation

I'm building an Angular 7 application using #angular/material. When I load the application for the first time, the Datatable renders correctly, but when I call any function, example - delUser, after deleting a user from the database, it's meant to render the table immediately, but it doesn't until I refresh the whole page. I've tried everything, but to no avail.
Here's my code:
import { Component, OnInit, ViewChild, TemplateRef } from '#angular/core';
import { UserService } from 'src/app/services/user.service';
import { MatTableDataSource } from '#angular/material/table';
import { MatSort } from '#angular/material/sort';
import { MatPaginator } from '#angular/material/paginator';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
pgtitle:string = "Manage Users";
dataSource:any;
displayedColumns:string[] = ['userName','email','roleId','userType','Actions'];
#ViewChild(MatSort, {static: true}) sort: MatSort;
#ViewChild(MatPaginator) paginator: MatPaginator;
constructor(
private service:UserService
){}
ngOnInit(): void {
this.getAllUsers();
}
applyFilter(filterValue:String){
this.dataSource.filter = filterValue.trim().toLowerCase();
}
getAllUsers(){
this.service.getAllUsers().subscribe( result => {
this.dataSource = new MatTableDataSource(result);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});
}
delUser(id){
this.service.deleteUser(id).subscribe(result => {
this.getAllUsers();
});
}
Maybe you can try this:
this.service.getAllUsers().subscribe( result => {
this.dataSource = null; //add this
this.dataSource = new MatTableDataSource(result);
this.dataSource.paginator = this.paginator;
this.dataSource.sort = this.sort;
});

Angular 7/8 - How to get url parameters in app component

I have Single sign on in place but for testing I want to read the values from the url localhost:4200/?id=test&name=testing&email=testing#test.com and pass them to an API in app component.
there will be a flag on which basis I will reading from url instead of using single sign on function
if (url_enabled == true) {
getParamsFromUrl()
} else {
singleSignOn()
}
I tried ActivatedRoute but it doesn't seem to be working.
I have tried queryParams, params, url, queryParamsMap but none of these seems to be working. all I get is empty value.
inside app component
app.component.ts
getParamsFromUrl() {
this._router.events.subscribe((e) => {
if (e instanceof NavigationEnd) {
console.log(e.url)
}
})
}
this.route.queryParams.subscribe(params => {
console.log(params);
})
app.component.html
<router-outlet></router-outlet>
app-routing.module.ts
const routes: Routes = [
{path:'*/:id', component: AppComponent},
];
I have tried whatever I could found on stackoverflow or other blogs. Can somebody point out what am I missing here?
For this route:
You can try this way:
const routes: Routes = [
{path:'*/:id', component: AppComponent},
];
In AppComponent .ts file:
constructor(
private activatedRoute: ActivatedRoute,
) { }
ngOnInit() {
this.activatedRoute.params.subscribe(params => {
const id = params['id'];
console.log('Url Id: ',id);
}
OR
ngOnInit() {
this.activatedRoute.queryParams.subscribe(params => {
const id = +params.id;
if (id && id > 0) {
console.log(id);
}
});
}
first of all there is an url with queryParams like yours :
localhost:4200/?id=test&name=testing&email=testing#test.com
in this way tou get to the queryparams with ActivatedRoute object lik :
this.name = this.activatedRoute.snapshot.queryParamMap.get('name'); // this.name = 'testing'
Or :
this.activatedRoute.queryParams.subscribe(params => {
this.name= params['name'];
});
and the other way is
localhost:4200/test/testing/testing#test.com
you use for sync retrieval (one time) :
this.name = this.activatedRoute.snapshot.ParamMap.get('name');
Angular comes us with the ActivatedRoute object. We can access the URL parameter value in same way its done above with little difference. Data in this type can be accessed with two different ways. One is through route.snapshot.paramMap and the other is through route.paramMap.subscribe. The main difference between the two is that the subscription will continue to update as the parameter changes for that specific route.
ngOnInit() {
this.route.paramMap.subscribe(params => {
this.userType = params.get("userType")
})
}
You need to create a new component and update the routing configuration as follows:
First, create a new component: MainComponent:
import { Component } from '#angular/core';
#Component({
selector: 'main',
template: `<router-outlet></router-outlet>`,
})
export class MainComponent {
constructor() { }
}
Then, update your AppModule:
import { AppComponent } from './app.component';
import { MainComponent } from './main.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{path: '', component: AppComponent}
])
],
declarations: [ MainComponent, AppComponent ],
bootstrap: [ MainComponent ]
})
export class AppModule { }
Finally, you'll need to update your index.html file(Make sure to load the brand new component instead of the AppComponent):
<main>loading</main>
Now you'll be able to read your parameters as requested in your AppComponent:
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Params } from '#angular/router';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
params: Params;
constructor(private route: ActivatedRoute){}
ngOnInit() {
this.route.queryParams.subscribe((params: Params) => {
this.params = params;
console.log('App params', params);
const id = params['id'];
console.log('id', id);
});
}
}
See a working example here: https://read-params-app-component.stackblitz.io/?id=test&name=testing&email=testing#test.com.
And find the source code here.
I hope it helps!
You can try like this
constructor(
private activatedRoute: ActivatedRoute
)
ngOnInit() {
this.activatedRoute.paramMap
.pipe(
tap(console.log(this.activatedRoute.snapshot.paramMap.get(
"id"
)))
).subscribe()
}
Let me know if you need any help
Using Transition from #uirouter/core makes it easy to get params from url.
import {Transition} from '#uirouter/core';
#Component()
export class MyComponent {
public myParam = this.transition.params().myParam;
public constructor(public transition: Transition) {}
}
I used jquery inside angular 8 and got the href using jquery $ variable after declaring it in app component.
import { query } from '#angular/animations';
declare var $: any;

Issue getting events from Eventbrite API

I'm building a school project using angular js and node js as a backend, I'm trying to display the event in my front-end using Angular JS from EventBrite, After spending a few hours checking different tutorial I wrote this code
Node JS code:
router.get('/', (req, res)=>{
axios.get(`${EventsBriteAPI}`).then(result=>{
let relevantData = result.data.data.events
res.status(200).json(relevantData);
console.log(results );
})
.catch(error => {
res.status(500).send(error);
})
});
My service code:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class EventsService {
uri = 'http://localhost:4600/events';
constructor(private httpClient: HttpClient) {}
getAllEvents(){
return this.httpClient.get(this.uri);
}
}
My component code
import { Component } from '#angular/core';
import { EventsService } from './events.service';
import { Observable } from 'rxjs/internal/Observable';
#Component({
selector: 'events',
templateUrl: 'events.Component.html'
})
export class EventsComponent {
title = "List of events";
eventObservable : Observable<any[]> ;
constructor(service: EventsService){
this.eventObservable = service.getAllEvents();
console.log(this.eventObservable);
}
}
When I'm running my code I'm getting this error
src/app/component/events/events.component.ts(21,5): error TS2322: Type 'Observable' is not assignable to type 'Observable'.
The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?
Type 'Object' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more. and It's not displaying anything in my front-end
Could you please help me with that.
we don't need to use Observable type variable unless you are using async pipe or for any specific requirement.
You can do some like below,
EventsComponent.ts
eventObservable: any = [];
constructor(private service: EventsService) {
this.service.getAllEvents().subscribe((response: any) =>{
this.eventObservable = response;
console.log(this.eventObservable);
});
}
we generally use ngOnInit() for calling an api data not in the constructor().

this.zone.run() - Ngzone error

I have a problem with sails + sails socket + angular4
import { Component, OnInit, NgZone } from '#angular/core';
import { routerTransition } from '../../router.animations';
import { Http } from '#angular/http';
import * as socketIOClient from 'socket.io-client';
import * as sailsIOClient from 'sails.io.js';
#Component({
selector: 'app-tables',
templateUrl: './tables.component.html',
styleUrls: ['./tables.component.scss'],
animations: [routerTransition()]
})
export class TablesComponent implements OnInit {
io:any;
smartTableData:any;
constructor(public http: Http, private zone: NgZone) {
this.io = sailsIOClient(socketIOClient);
this.io.sails.url = "http://localhost:1337";
this.io.socket.get('/posts', function(resData, jwr) {
console.log (resData);
return resData;
});
this.io.socket.on('updateposts', function(data) {
this.zone.run(() => {
this.smartTableData = data;
});
});
}
ngOnInit() {
}
}
When the socket broadcasts data, the line this.socket.on("updataposts") is run, but ngZone does not work.
zone.js:196 Uncaught TypeError: Cannot read property 'run' of undefined
I want to update data to view when receiving socket data. Please help me!
Thank you!

Resources