Identifying object ID in JSON by using object property In angular - json

I'm working on simple book management app. When user clicks on "Add to favorites, That book will be added to favorites page. Up to now, I have build start page, login page, and register page. I'm using JSON as a database (books.json and users.json) and using JSON-server to host the data. Here my Question is, When the new user is created, How to create Empty Wishlist automatically? And based on Mail id, how to get Id of that object? I have tried some methods in YouTube and documentation. but I was failed.
user.json
[
{
"id": 1,
"userName":"Deepak Sharma",
"Password":"dep#123!",
"Phone":"9988776655",
"Email":"Deepak#gmail.com",
"UserType":"Customer",
"WishList": [1,2,3],
"Completed":[4,5,6]
},
{
"username": "test1",
"Password": "test1",
"Phone": 123456,
"Email": "test1#gmail.com",
"id": 2
}
]
login-page.component.ts
import { HttpClient } from '#angular/common/http';
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'app-login-page',
templateUrl: './login-page.component.html',
styleUrls: ['./login-page.component.css']
})
export class LoginPageComponent implements OnInit {
public loginForm!: FormGroup;
constructor(private formBuilder : FormBuilder, private http: HttpClient, private router: Router) { }
ngOnInit(): void {
this.loginForm = this.formBuilder.group({
Email: ['', Validators.required],
Password: ['', Validators.required]
})
}
login(){
this.http.get<any>("http://localhost:3500/Users")
.subscribe(res=>{
const user = res.find((a:any) =>{
return a.email === this.loginForm.value.email && a.password === this.loginForm.value.password
});
if (user) {
alert("Login Success!");
this.loginForm.reset();
this.router.navigate(['user'])
} else {
alert("User Not found. Create account !!");
}
}, err=>{
alert("Something Went Wrong");
})
}
}
and here is the code favorite-page.component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { LoginPageComponent } from '../login-page/login-page.component';
#Component({
selector: 'app-favourite-page',
templateUrl: './favourite-page.component.html',
styleUrls: ['./favourite-page.component.css']
})
export class FavouritePageComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

You can create a wish list with a format of your liking inside the function where you create the new user. The format can be JSON, a temporary array or an insert into a database.
I can also see that you're using a deprecated calling method of subscribe. Consider checking out the tutorials & documentation of Angular, rxjs an ngrx.

Related

How can I change the routing for a component taking in the status code

I am working on an angular project for learning. I want to find a way to change the routing based on the routing code that I receive. See my code below for my service.ts file. We were not able to get the toke api set up so I am just looking to switch routing based on 200 status code.
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http';
import { Observable, throwError, catchError } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class LoginService {
token:string = ""
// Login Logic
login(userName:string, password:string):Observable<any>{
return this.http.post('https://vanquish-p2.azurewebsites.net/api/UserC/Authenticate?UserName=' + userName +'&password=' + password,
// We need to add headers to specify content type
{headers: {'Content-Type':'application/json'}}
)
.pipe(
catchError((e) =>{
return throwError(e)
}
))
}
// Inject HttpClient into our service
constructor(private http:HttpClient) { }
}
This right here is my login component
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { LoginService } from '../login.service';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
// Adding in defaults to store info
userName:string = "";
password:string = "";
error:boolean = false;
// Create onsubmit to handle submissions
onSubmit():void{
console.log(this.userName, this.password)
this.loginService.login(this.userName, this.password)
.subscribe((data) =>{
console.log(data)
// Let's store the data in our service's string
this.loginService.token = data.token;
console.log(this.loginService.token)
// If we successfully login, let's redirect to the home page
this.router.navigate(['home'])
},
(error) =>{
console.log(error)
// Makes error message appear through ngIf
this.error = true;
})
}
//Inject login service to component to use methods
// Inject router for navigation
constructor(private loginService:LoginService, private router:Router) { }
ngOnInit(): void {
}

How to retrieve single product details from firebase realtime database in angular 9 and print it in html?

product.component.ts
import { AngularFireDatabase } from '#angular/fire/database';
import { ProductService } from './../product.service';
import { ActivatedRoute } from '#angular/router';
import { Component, OnInit} from '#angular/core';
#Component({
selector: 'app-product',
providers:[],
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
product;
object9;
constructor(public route: ActivatedRoute,public db: AngularFireDatabase) {
this.id= this.route.snapshot.paramMap.get('id');
console.log(this.id);
this.object9=this.db.object('products/'+this.id).valueChanges().subscribe(val =>{
console.log(val);
});
}
ngOnInit() {
}
}
product.component.html
{{ object9.fullName|async|json}}
Firebase realtime Database:
oshop-1df92
products
-M9vLP-mF2DAIMkkKVR_
email:
fullName:
-M9vLfD2r3PrQbXQiYot
-M9vSjV9lNVZ2QhIj63n
In console I am getting id printed and console.log(val) prints object having the id,but in html it is printing null.Why??
I am using latest angular 9 with latest version of firebase and angularfire.Oshop is name of project.
Please help me out.
By assigning the subscription to the variable object9 and not the data that you get from the subscription.
Instead replace your code of assinging the value by the following lines:
this.db.object('products/'+this.id).valueChanges().subscribe(val =>{
console.log(val);
this.object9= val
});
}
And now simply print the value in html using:
{{object9.fullname}}

Angular 6: use a service to get local json data

I have a movies.json that contain a list of movies and I want to create a MoviesServices to get the data where I want.
My MoviesServices:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { HttpErrorResponse } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class MoviesService {
movies: string[];
constructor(private httpService: HttpClient) {
this.getMovies();
}
getMovies() {
this.httpService.get('../../assets/movies.json').subscribe(
data => {
this.movies = data as string[];
console.log(this.movies); // My objects array
},
(err: HttpErrorResponse) => {
console.log(err.message);
}
);
console.log(this.movies); // Undefined
}
}
Firstly, I have no idea why the first console.log() works and the second not, can you tell me why ?
Here is my component where I need to get the data:
import { Component, OnInit } from '#angular/core';
import { MoviesService } from '../services/movies/movies.service';
#Component({
selector: 'app-movies',
templateUrl: './movies.component.html',
styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {
title = 'films-synopsys';
movies;
constructor(private myService: MoviesService) {}
ngOnInit() {
console.log(this.myService.movies); // Undefined
}
}
Of course this is not working. Can you tell me how must I do ? I'm newbie angular
So basically you need to return an Observable from your service and then subscribe to it from your Component. You can then assign your response to the Component property movies
Try this:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class MoviesService {
constructor(private httpService: HttpClient) { }
getMovies() {
return this.httpService.get('../../assets/movies.json');
}
}
And in your Component:
import { Component } from '#angular/core';
import { MoviesService } from './movies.service';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
title = 'films-synopsys';
movies;
constructor(private myService: MoviesService) {}
ngOnInit() {
this.myService.getMovies()
.subscribe(res => this.movies = res);
}
}
Here's a Sample StackBlitz for your ref.
Change your method to return an Observable which you can subscribe to:
import { Observable } from 'rxjs/Observable';
...
getMovies(): Observable<string []> {
this.httpService.get('../../assets/movies.json').subscribe(
data => {
this.movies = data as string[];
return this.movies;
},
(err: HttpErrorResponse) => {
console.log(err.message);
}
);
}
In your calling code:
import { Subscription } from 'rxjs/Subscription';
this.myService.getMovies().subscribe(movies => {
console.log(movies); // My objects array
}
The reason the first console log works is because you are doing it within an observable's subscription. Subscriptions have three states, Next, Error, Complete and so when you console log the first time, within the subscription next state you get the value that was pushed out from the event stream.
In your component the reason why it doesn't work is due to the fact that observables are lazy, and that you need to initialize the data by calling this.myService.getMovies() first to make the subscription happen.
A better way to do this would been to pass observables around and use async pipe in the html template.

OnInit list not displaying

I'm creating an Angular6 crud app and I have a list of users in my database. I am able to retrieve my list when I call getAllUsers but it does not display in the UI. The only time I see a row being displayed in the table is when I manually enter a new User but it does not display the data previous to my entry. What am I doing wrong?
import { Component, OnInit } from '#angular/core';
import { UserDataService } from './user-data.service';
import { User } from './user';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [UserDataService]
})
export class AppComponent implements OnInit{
users: User[]=[];
constructor(private userDataService: UserDataService) {}
public ngOnInit() {
debugger
this.userDataService
.getAllUsers()
.subscribe(
(users) => {
this.users = users;
}
);
}
onAddUser(user) {
this.userDataService
.addUser(user)
.subscribe(
(newUser) => {
this.users = this.users.concat(newUser);
}
)
}
onRemoveUser(user){
this.userDataService
.deleteUserById(user.id)
.subscribe(
(_) => {
this.users = this.users.filter((u) => u.id !== user.id);
}
);
}
getUser() {
return this.userDataService.getAllUsers();
}
}
APP COMPONENT HTML
<app-user-list-header (add)="onAddUser($event)"></app-user-list-header>
<table>
<th>ID</th>
<th>NAME</th>
<tr *ngFor = "let user of users">
<td>{{user.id}}</td>
<td>{{user.userName}}</td>
</tr>
</table>
USER DATA SERVICE
import { Injectable } from '#angular/core';
import { User } from './user';
import { ApiService } from './api.service';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class UserDataService {
constructor(private api: ApiService) { }
addUser(user: User): Observable<User> {
return this.api.createUser(user);
}
getAllUsers(): Observable<User[]> {
return this.api.getAllUsers();
}
updateUser(user: User): Observable<User> {
return this.api.updateUser(user);
}
getUserById(userId: number): Observable<User> {
return this.api.getUserById(userId);
}
deleteUserById(userId: number): Observable<User> {
return this.api.deleteUserById(userId);
}
}
USER LIST HEADER
import { Component, OnInit, Output, EventEmitter } from '#angular/core';
import { User } from '../user';
#Component({
selector: 'app-user-list-header',
templateUrl: './user-list-header.component.html',
styleUrls: ['./user-list-header.component.css']
})
export class UserListHeaderComponent implements OnInit {
newUser: User = new User();
#Output()
add: EventEmitter<User> = new EventEmitter();
constructor() { }
ngOnInit() {
}
addUser() {
this.add.emit(this.newUser);
this.newUser = new User();
}
}
USER LIST HEADER HTML
<header class="userHeader">
<h1>Users</h1>
<input class="new-user" placeholder="Enter User" autofocus="" [(ngModel)]="newUser.userName" (keyup.enter)="addUser()">
</header>
API SERVICE
import { Injectable } from '#angular/core';
import { environment } from '../environments/environment';
import { User } from './user';
import { Http } from '#angular/http';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '#angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError } from "rxjs/operators";
const API_URL = environment.apiUrl;
#Injectable({
providedIn: 'root'
})
export class ApiService {
constructor(private http: HttpClient) {
}
public createUser(user: User): Observable<User> {
const headers = {headers: new HttpHeaders({
'Content-Type': 'application/json'
})};
return this.http
.post(API_URL + '/users', user).pipe(
map(response => {
return new User(response);
}), catchError(this.handleError)
)
}
public getAllUsers(): Observable<User[]> {
return this.http
.get(API_URL + '/users').pipe(
map(response => {
var users = [response];
return users.map((user)=> new User(user));
}), catchError(this.handleError))
}
The issue is, you don't need to subcribe a new user to the observable here in the AppComponent again after you have done it before:
.subscribe(
(newUser) => {
this.users = this.users.concat(newUser);
}
)
because it is already added to the user array by this mean: this.userDataService.addUser(user), that says you inserted the same value twice to the observer.
So what you need to do is, in the userdata service, plug an observer to the rest api that fetches data regularily to the adapter getAllUsers like this:
getAllUsers(): Observable<user[]> {
// some intermediate post call happens here
this.api.getAllUsers().subscribe((users) => users.map((user)=>this.users.push(user)));
return of(this.users);
}
This will update the state of users whenever a new value added to the users base, or piped from the rest call, so you do never have to subcribe the same value more than once from the same observer, this will cause duplication of data.
I couldn't find an online api that allows post calls, so you could find your ease figuring that I said above using your own tools, but for a same-domain GET api service, I made an example in this term visible to your eyes here:
https://stackblitz.com/edit/angular-rndqsd.
Taking countries as users for sake of vocabulary-allowance.

Angular 2/4 - Can't resolve all parameters for GameEditComponent: ([object Object], [object Object], ?)

I am developing the services of my application, but when I try to load the page it shows the following error:
Can't resolve all parameters for GameEditComponent: ([object Object],
[object Object], ?).
I tried in the service to put as an array or just leave any, but even then the error continued
game-edit.service.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Observable } from 'rxjs';
#Injectable()
export class GameEditService {
constructor(private http: Http) { }
getGame(id): Observable<any> {
return this.http.get('http://localhost:8080/lightning/api/game' + id).map(res => res.json()).catch(error => {
throw new Error(error.message);
});
}
getManufactures(): Observable<any> {
return this.http.get('http://localhost:8080/lightning/api/manufacture').map(res => res.json()).catch(error => {
throw new Error(error.message);
});
}
getPlatforms(): Observable<any> {
return this.http.get('http://localhost:8080/lightning/api/platform').map(res => res.json()).catch(error => {
throw new Error(error.message);
});
}
}
game-edit.component.ts
import { ActivatedRoute, Params } from '#angular/router';
import { Component, OnInit } from '#angular/core';
import { GameEditService } from './game-edit.service';
#Component({
moduleId: module.id,
selector: 'app-game-edit',
templateUrl: './game-edit.component.html',
styleUrls: ['./game-edit.component.css', '../styles.css' ]
})
export class GameEditComponent implements OnInit {
constructor(private activatedRoute: ActivatedRoute, private gameEditService: GameEditService, private id) {
this.gameEditService.getPlatforms().subscribe(platforms => {
console.log(platforms);
}), erro => console.log(erro);
this.gameEditService.getManufactures().subscribe(manufactures => {
console.log(manufactures);
}), erro => console.log(erro);
}
ngOnInit() {
this.activatedRoute.params.subscribe((params: Params) => {
this.id = params['id'];
console.log(this.id);
});
this.gameEditService.getGame(this.id).subscribe(game => {
console.log(game);
}), erro => console.log(erro);
}
onSubmit(form){
console.log(form);
}
verificaValidTouched(campo){
return !campo.valid && campo.touched;
}
aplicaCssErro(campo){
return {
'subError': this.verificaValidTouched(campo)
}
}
}
This is the json that is coming, the first is for a selected game, the second is for the platforms and the third is for the manufacturers
json game selected
{
"id":1,
"name":"Street Fighter",
"category":"luta",
"price":20.5,
"quantity":1000,
"production":true,
"description":"descricao",
"image":"ps4.jpg",
"manufacture":
{
"id":1,
"name":"Sony",
"image":"ps4.jpg",
"imageFullPath":"http://localhost:8080/lightning/images/ps4.jpg"
}
}
json platforms
{
"id":1,
"name":"PC",
"image":"ps4.jpg",
"imageFullPath":"http://localhost:8080/lightning/images/ps4.jpg"
}
json manufactures
{
"id":1,
"name":"Sony",
"image":"ps4.jpg",
"imageFullPath":"http://localhost:8080/lightning/images/ps4.jpg"
}
Console
I'm using angular cli with with all packages in the most current versions.
I do not know if maybe this error is because of the platforms you have inside the game, or some other code problem, if you know something that could do to repair, I tried several solutions that I found through the internet, but none worked.
Thanks in advance.
The problem is the last argument in the component's constructor, private id. Angular will try to resolve this dependency, but can't find an injectable class for id. When looking at the code, I think there is no need to inject id into the constructor. Just define it as a property on your component:
// ... import statements
#Component({
moduleId: module.id,
selector: 'app-game-edit',
templateUrl: './game-edit.component.html',
styleUrls: ['./game-edit.component.css', '../styles.css' ]
})
export class GameEditComponent implements OnInit {
private id; // put the declaration of id here
// remove id declaration from the constructor, no need to inject it
constructor(private activatedRoute: ActivatedRoute,
private gameEditService: GameEditService) { // ...constructor code}
// other code
}
I solved it otherwise: My problem was that the HttpClient has a rare condition, it's not the same "import" line on the component that on the app.module...
On the Component is this:
import { HttpClient } from '#angular/common/http';
in app module is this:
import { HttpClientModule } from '#angular/common/http';