I am doing an Angular 4 application with node js backend. I did the login form, and all is good I want to implement the function "remember me".
This my login service:
import { Injectable } from '#angular/core';
#Injectable()
export class loginService{
rememberMe: boolean;
constructor() { }
login(credentials) {
sessionStorage.setItem('Name', credentials.firstName);
sessionStorage.setItem('token', credentials.token);
}
getCostumer() {
const user = {
Name: sessionStorage.getItem('firstName'),
token: sessionStorage.getItem('token')
}
This is the component:
constructor(private signInService: SignInService, private router: Router,
public dialog: MatDialog, private authService: AuthService) { }
ngOnInit() { }
login(costumer) {
this.loginService.login(costumer).subscribe((data) => {
this.authService.login(data);
this.router.navigate(['home']);
this.dialog.closeAll();
}, err => {
this.message = err._body;
console.log(this.message);
});
}
}
Use localStorage instead of sessionStorage
In your case, you can do something like this:
if (isRemberMeChecked) {
...
localStorage.setItem('Name', credentials.firstName);
localStorage.setItem('token', credentials.token);
...
} else {
...
sessionStorage.setItem('Name', credentials.firstName);
sessionStorage.setItem('token', credentials.token);
...
}
If you want to get isRemberMeChecked value globally you can use angular service
What you want to do here is use localStorage for the rememberMe and credentials.firstName. The credentials.token you can store in the sessionStorage:
login(credentials) {
localStorage.removeItem('Name');
localStorage.removeItem('RememberMe');
sessionStorage.setItem('token', credentials.token);
if(rememberMe){
localStorage.setItem('Name', credentials.firstName);
localStorage.setItem('RememberMe', JSON.stringify(this.rememberMe));
}
}
After a reload it will fetch the RememberMe and Name:
if(JSON.parse(localStorage.getItem('RememberMe')) !== null)
{
this.name = localStorage.getItem('Name');
this.rememberMe = JSON.parse(localStorage.getItem('RememberMe'));
}
Related
I was trying to reload a component using the below code
reload() {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/'], { relativeTo: this.route, queryParamsHandling: 'preserve' });
}
But in a service file, I was using the below block of code in a service file to get query params
constructor(
private route: ActivatedRoute,
private generalSettings: GeneralSettingsService,
private httpClient: HttpClientService,
private toastrService: ToastrService,
) {
this.route.queryParams.subscribe(params => {
this.module = params['module'];
this.env = params['env'];
console.log(this.module, this.env)
});
}
Once I reload the component, I am not able to get the query params.
I have an angular function that looks for a 'list' parameter in the initial URL, and if found will go out and get information. Otherwise I want to get the geolocation. I don't want to get geolocation if the URL param is present. Am I even using the right terms?
constructor(private router: Router, private activatedRoute: ActivatedRoute, private providerService: ProviderService) { }
ngOnInit(): void {
this.processURL();
this.processGPS();
}
private processURL() {
console.log('1a');
this.activatedRoute.queryParams.forEach(item => {
if (item['list']) {
console.log('1b');
this.providerService.setCurrentProvider(item['list']);
}
});
}
private processGPS() {
console.log('2a');
window.navigator.geolocation.getCurrentPosition(position => {
this.providerService.findByGeo(position.coords).subscribe(providers => {
if (providers.length > 0) {
console.log('2b');
this.providerService.setCurrentProvider(providers[0]);
}
},
() => {
console.log('GeoLocation Not available or disabled');
}).unsubscribe();
});
}
queryParams is an Observable, not an array, so you should subscribe to it.
What I did:
subscribe to the this.activatedRoute.queryParams
check if the list property exists on the parameters
If it does exist call some service
Else if it does not exist use GPS
ngOnInit(){
this.activatedRoute.queryParams.subscribe( params => {
if( typeof params.list !== 'undefined')
this.providerService.setCurrentProvider( params.list );
else
this.processGPS();
});
}
Move the processGPS to an else when the list parameter is not found:
ngOnInit(): void {
this.processURL();
}
private processURL() {
console.log('1a');
this.activatedRoute.queryParams.subscribe(item => {
if (item['list']) {
console.log('1b');
this.providerService.setCurrentProvider(item['list']);
} else {
this.processGPS();
}
});
}
can any one please tell me why I can not loop through this array?
In ngOnInit, everything works fine. I got an array that I successfully display in the template.
But in ngAfterViewInit, console.log show the array but when looping through with "for of" or "forEach", nothing works.
import { JobsService } from '../jobs.service';
import {Job} from '../models/Job';
#Component({
selector: 'app-job',
templateUrl: 'job.component.html'
})
export class JobComponent implements OnInit, AfterViewInit {
title = 'Job';
jobs: Job[] = [];
InProcess = '';
CurrentPartner = '';
ShowProcess = false;
sended = '';
constructor(private jobsService: JobsService) {
}
ngOnInit() {
this.jobs = this.jobsService.getJobs();
}
ngAfterViewInit() {
console.log(this.jobs); // Show the array
// Nothing happened when looping through the array
this.jobs.forEach((oneJob) => {
console.log(oneJob);
});
}
}
Screenshot of the console in Google Chrome
The content of the service:
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import {Job} from './models/Job';
interface IJob {
message: string;
jobs: any[];
}
#Injectable({
providedIn: 'root'
})
export class JobsService {
constructor(private httpClient: HttpClient) { }
private REST_API_SERVER = 'http://localhost:8080/myband/api/getjobs.php';
private REST_API_SERVER_SEND = 'http://localhost:8080/myband/api/sendjob.php';
jobList: Job[] = [];
errorMessage: any;
message: string;
static handleError(err: HttpErrorResponse) {
let errorMessage = '';
if (err.error instanceof ErrorEvent) {
errorMessage = `An error occurred: ${err.error.message}`;
} else {
errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
}
console.error(errorMessage);
return throwError(errorMessage);
}
public getJobs() {
this.requestJobs().subscribe(
iJob => {
this.message = iJob.message;
for (const job of iJob.jobs) {
const oneJob: Job = new Job(job);
this.jobList.push(oneJob);
}
},
error => this.errorMessage = error as any
);
return this.jobList;
}
public requestJobs(): Observable<IJob> {
return this.httpClient.get<IJob>(this.REST_API_SERVER).pipe(
catchError(JobsService.handleError)
);
}
}
The first thing I want to say to you is about isolation of responsibilities.
Your service must have just one job: provider one way to access your data; It means your logic inside getJobs() method could be done in your component.
export class JobsService {
constructor(
private httpClient: HttpClient,
) {}
private REST_API_SERVER = 'http://localhost:8080/myband/api/getjobs.php';
public requestJobs(): Observable<IJob> {
return this.httpClient.get<IJob>(this.REST_API_SERVER);
}
}
Now, you can handler your data in your component.
import { JobsService } from '../jobs.service';
#Component({
selector: 'app-job',
templateUrl: 'job.component.html'
})
export class JobComponent implements OnInit, AfterViewInit {
title = 'Job';
jobs$;
InProcess = '';
CurrentPartner = '';
ShowProcess = false;
sended = '';
constructor(private jobsService: JobsService) {
}
ngOnInit() {
this.jobs$ = this.jobsService.requestJobs();
}
ngAfterViewInit() {
this.jobs$
.pipe(
map(() => {}), // change your data here
catchError(() => {}) // handler your error here;
)
.subscribe(
() => {} // have access to your final data here.
);
}
}
Things to know:
You can remove the subscribe() execution and use the async pipe in your template;
The use of the operator map in pipe() is optional, you can handler your final data directly from your first callback subscribe().
You can convert your Observable to Promise using toPromise() method in one observable. Don't forgot async / await in your ngAfterViewInit.
Let me know if there is something I can help.
Try:
Object.keys(this.jobs).forEach(job => {
console.log(this.jobs[job]);
});
Try to assign an iterator function with below part replacement by this code:
// Nothing happened when looping through the array
this.jobs.forEach(oneJob, function(value, key) {
console.log(key + ': ' + value);
});
Usage of forEach in AngularJS:
For documentation try to check AngularJS forEach Docs
Syntax:
someIterable.forEach(object, iterator, [context])
Please check below example
class Job {
id: any;
status: any;
constructor(obj: any) {
this.id = obj.id;
this.status = obj.status;
}
}
let arr = [
{
id: 1,
status: "job"
}, {
id: 2,
status: "job2"
}
];
let newArr: any = [];
arr.forEach(a => {
let obj: Job = new Job(a);
newArr.push(obj);
})
console.log(newArr);
newArr.forEach((a: any) => {
console.log(a);
})
Hii all I am trying to post data to json server using post method , but unfortunately I have erros, my app have buttons follow, likes etc , I want when user clicks follow numbers increase and saved to the json file , so now when user clicks button I get the following error :
Note: am using fakes json server : Fake Json server
Error: Insert failed, duplicate id
at Function.insert (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\lodash-id\src\index.js:49:18)
at C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\lodash\lodash.js:4374:28
at arrayReduce (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\lodash\lodash.js:683:21)
at baseWrapperValue (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\lodash\lodash.js:4373:14)
at LodashWrapper.wrapperValue (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\lodash\lodash.js:9052:14)
at create (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\lib\server\router\plural.js:221:52)
at Layer.handle [as handle_request] (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\express\lib\router\route.js:137:13)
at next (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\express\lib\router\route.js:131:14)
at Route.dispatch (C:\Users\jelly\AppData\Roaming\npm\node_modules\json-server\node_modules\express\lib\router\route.js:112:3)
POST /statuses 500 13.873 ms - -
Here is service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import {Status } from '../model/statuses.model';
import { Comment } from '../model/comments.model';
#Injectable({
providedIn: 'root'
})
export class UserService {
status: Status[];
constructor(private http: HttpClient) { }
statusUrl = 'http://localhost:3000/statuses';
commentsUrl = 'http://localhost:3000/comments';
getStatuses() {
return this.http.get<Status[]>(this.statusUrl);
}
addStatus(status: Status) {
return this.http.post(this.statusUrl, status);
}
addComments(comment: Comment) {
return this.http.post(this.commentsUrl, comment);
}
}
here is ts file :
import { Component, OnInit } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { UserService } from '../service/user.service';
import { Status } from '../model/statuses.model';
import { Comment } from '../model/comments.model';
import {FormBuilder, FormGroup, Validators} from '#angular/forms';
#Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.scss']
})
export class UserProfileComponent implements OnInit {
status: Status[];
comment: Comment[];
constructor(private formBuilder: FormBuilder, private http: HttpClient, private userService: UserService) { }
addForm: FormGroup;
ngOnInit() {
this.addForm = this.formBuilder.group({
id: [],
name: ['', Validators.required],
city: ['', Validators.required],
description: ['', Validators.required],
});
this.userService.getStatuses()
.subscribe( data => {
this.status = data;
console.log(data);
console.log(this.status);
});
}
addComments() {
this.userService.addComments(this.addForm.value)
.subscribe(data => {
this.comment.push(this.addForm.value);
});
}
followButtonClick(statusId) {
const statusToUpdate = this.status.filter(status => status.id === statusId)[0];
statusToUpdate.followers++;
statusToUpdate.following++;
this.persistStatus(statusToUpdate);
}
likesButtonClick(statusId) {
const statusToUpdate = this.status.filter(status => status.id === statusId)[0];
statusToUpdate.like++;
this.persistStatus(statusToUpdate);
}
persistStatus(status) {
this.userService.addStatus(status)
.subscribe(data => {
this.status = status;
});
}
}
Here is json file :
{
"statuses": [
{
"id": 1,
"statusId": 20,
"likes": 121,
"following": 723,
"followers": 4433
}
]
}
Here is model
export class Status {
id: number;
statusId: number;
like: number;
following: number;
followers: number;
}
what am I doing wrong in my code ????
From documentation of the fake json-server you are using,:
Id values are not mutable. Any id value in the body of your PUT or
PATCH request will be ignored. Only a value set in a POST request will
be respected, but only if not already taken.
You are trying to update an existing status, so you need a put call not post. Something like this:
updateStatus(status: Status) {
return this.http.put(this.statusUrl + '/' + status.id, status);
}
And use it in the persistStatus function.
persistStatus(status) {
his.userService.updateStatus(status)
.subscribe(data => {
this.status = [status];
});
}
I am running two checks and then conditionally populating some data to certain routes if both conditions are met. In my room.component.html file I am using an *ngIf for this:
<div *ngIf="isLoggedIn() && isRoomRoute()" class="others">
... do some work
</div>
My room.component.ts file looks like this:
import { RouteService } from './../../data/route.service';
import { Component } from '#angular/core';
import { AuthenticationService } from './../../data/authentication.service';
import { Router } from '#angular/router';
#Component({
selector: 'app-room',
templateUrl: './room.component.html',
styleUrls: ['./room.component.less']
})
export class RoomComponent {
model: any = {};
loading = false;
username;
password;
routeUrl;
private url = 'http://localhost:5000';
constructor(private authenticationService: AuthenticationService,
private router: Router,
private routeService: RouteService,
private appComponent: AppComponent) { }
isLoggedIn() {
this.loading = true;
if (this.authenticationService.isAuthenticated()) {
return true;
}
}
isRoomRoute(routeUrl) {
if (this.routeService.isRoomRoute(this.routeUrl)) {
return true;
}
}
}
As you can see above, the second check is using a function from my routeService. That function looks like this:
isRoomRoute(routeUrl) {
if (routeUrl.includes('staff')) {
console.log('This url: ' + routeUrl + ' is a roomRoute');
return true;
} else {
console.log('This url: ' + routeUrl + ' is NOT a room route');
return false;
}
}
This urls are being tracked in my app.component, which is using the routeService in the constructor, and looks like this:
constructor(private routeService: RouteService,
private router: Router)
{
this.router.events.subscribe((route) => {
let routeUrl = route.url;
this.routeService.sendRoute(routeUrl);
this.routeService.isRoomRoute(routeUrl);
});
}
I am successfully getting the right result from my routerService's "isRoomRoute" function, but I am getting an "undefined" error when I try and pass that result to my room component, even though I though I am calling the routeService in that component. So my question is, what am I missing that's making the result "undefined" from the room component? How do I pass a boolean value from the result of the isRoomRoute() function in the routeService to my room component?