Ionic How to Pass variable to firebase equalTo method - javascript

I have already managed to fetch data form firebase.problem is when i'm going to filter data according to the id it doesn't work.
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { AngularFireDatabase, AngularFireList ,} from 'angularfire2/database';
import { Observable } from 'rxjs'
import { query } from '#angular/core/src/render3';
import { Key } from 'protractor';
class postview {
constructor(public title) { }
}
#Component({
selector: 'app-news-view',
templateUrl: './news-view.page.html',
styleUrls: ['./news-view.page.scss'],
})
export class NewsViewPage implements OnInit {
id: string;
public books: AngularFireList<postview[]>;
itemlol: Observable<any>;
posts: Observable<any[]>;
constructor(private route: ActivatedRoute , db: AngularFireDatabase) {
let idp :string = this.id;
this.posts = db.list('Posts' ,ref => {
return ref.orderByChild('Post_Id').equalTo(idp)
}).valueChanges();
// this.itemlol= db.object('Posts').valueChanges();
}
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
console.log(this.id);
console.log(this.posts);
}
}
in the section return ref.orderByChild('Post_Id').equalTo(idp) I need to pass variable in equalTo(). It should change according to the user instructions
Example
equalTo(01)
equalTo(02)
This is my firebase database:

The constructor is called before ngOnInit so the value for this.id will be undefined at the time of the query.
You should get the Parameters in the constructor
this.id = this.route.snapshot.paramMap.get('id');
let idp :string = this.id;
this.posts = db.list('Posts' ,ref => ref.orderByChild('Post_Id').equalTo(idp) ).valueChanges();

Related

Why is my Angular Service not assigning a filtered result to my property?

I setup a service called 'bankService' which is being used by my 'user' component. The 'user' component is receiving the data from the service correctly but I am unable to assign a filtered result to my 'currentAccount' property. I am filtering by 'id' from the list of 'accounts' that is being returned from my service. Any help with an explanation would be appreciated!
Model
export interface Account {
id: number;
accountHolder: string;
checking: number;
savings: number;
}
Service
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { elementAt, Observable } from 'rxjs';
import { Account } from '../models/Account';
import { Transaction } from '../models/Transaction';
#Injectable({
providedIn: 'root',
})
export class BankServiceService {
private apiUrl = 'http://localhost:5000/accounts';
constructor(private http: HttpClient) {}
getAccounts(): Observable<Account[]> {
return this.http.get<Account[]>(this.apiUrl);
}
}
Component
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from '#angular/router';
import { Account } from 'src/app/models/Account';
import { BankServiceService } from 'src/app/services/bank-service.service';
#Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css'],
})
export class UserComponent implements OnInit {
currentAccount: Account[] = [];
accountId: number;
accountHolder: string;
checkingAmount: number;
savingsAmount: number;
constructor(
private route: ActivatedRoute,
private bankService: BankServiceService
) {}
ngOnInit(): void {
// gets the parameter for the url (the param is the account id)
this.accountId = this.route.snapshot.params['id'];
console.log('id: ', this.accountId);
// pulls in all accounts
this.bankService
.getAccounts()
.subscribe(
(accounts) =>
(this.currentAccount = accounts.filter(
(account) => account.id === this.accountId
))
);
console.log('current account: ', this.currentAccount);
}
}
If I'm not mistaking, your issue is this one:
the account id received from the backend is a number
the account id pulled from the url is a string
In the filter function you are using strict equality, and that's why no account id passes the condition in the filter callback
You can switch from strict equality to loose equality (==) or do something like this for the filter callback:
(account) => account.id.toString() === this.accountId

Retrieving the next item in an array by index in Angular 11

I have a list of employees in a JSON object in my service.ts file. It will be moved to a DB eventually. I know this is not the place for it. It's just for dev purposes. I am able to retrieve the employees by clicking on it and displaying them in a dynamic view component.
However, I want to be able to see the next employee on a button click without having to always go back to the main list. I am able to retrieve the index and increment the index on click. I just can't get the route to display the data for that index.
The HTML is pretty basic a simple button with a click method. The Service file looks like this:
import {HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { Employee } from '../models/employee.models';
#Injectable({
providedIn: 'root'
})
export class EmployeesService {
private listEmployees: Employee[] = [...regular json object...];
constructor() { }
getEmployees(): Employee[] {
return this.listEmployees;
}
getEmployee(id: number): Employee {
return this.listEmployees.find(e => e.id === id);
}
}
And my employee.component.ts file
import { ActivatedRoute } from '#angular/router';
import { EmployeesService } from './../../../services/employees.service';
import { Component, OnInit } from '#angular/core';
import { Employee } from 'src/app/models/employee.models';
import { Router } from '#angular/router';
#Component({
selector: 'employee',
templateUrl: './employee.component.html',
styleUrls: ['./employee.component.scss']
})
export class EmployeeComponent implements OnInit {
employee: Employee;
employees: Employee[];
index: number;
private _id: number;
constructor(
private _route: ActivatedRoute,
private _router: Router,
private _employeeService: EmployeesService
) { }
ngOnInit() {
this.employees = this._employeeService.getEmployees();
for ( this.index = 1; this.index < this.employees.length + 1; this.index++ ) {
this._route.paramMap.subscribe(params => {
this._id = +params.get('id')
console.log('this index:', this.index);
this.employee = this._employeeService.getEmployee(this._id);
});
}
}
viewNextEmployee() {
if( this.index < this.employees.length ){
this.index = this.index++;
console.log('this index:', this.index);
this._router.navigate(['/team', this._id])
} else {
this.index = 1;
}
}
}
I'm sorry, I can't really reproduce a working code. So many dependencies.

retrieving data from firebase in Angular

I have an angular module where I need to filter particular property of the data from firebase and store it in an array so that I can loop through it in my HTML.
This is my component.ts file
import { ToastrService } from 'ngx-toastr';
import { AngularFireDatabase, } from '#angular/fire/database';
import * as firebase from 'firebase';
import { ImageService } from '../../image.service'
import { AngularFireStorage } from '#angular/fire/storage';
#Component({
selector: 'app-mobile',
templateUrl: './mobile.component.html',
styleUrls: ['./mobile.component.css']
})
export class MobileComponent implements OnInit {
images: any;
name: string;
type: any;
filters = {};
nature :String;
value:string;
pictures:string[];
constructor(private storage: AngularFireStorage,
private db: AngularFireDatabase) {}
ngOnInit() {
this.db.list('/images').valueChanges()
.subscribe(images =>{
this.images = images;
})
}
cato() {
var ref = firebase.database().ref("/images");
ref.orderByChild("name").equalTo("nature").once("child_added")
.then(function(snapshot) {
snapshot.forEach(item => console.log(item.val().picture))
return this.item.val();
});
}
}
I am trying to filter the data to get only picture property in the data. Now I want to access all the list of picture values so that I can store it in a variable and access it in my HTML file.
Thank you in advance.

Cannot access variable outside the subscription

I have an component in angular. I get data from the API and I instantiate a new object to create a map. But I can't access a variable outside the subscribe function. I also can't access my method.
maps.service.ts
This part, get data form api
import { Injectable } from '#angular/core';
import {HttpClient} from '#angular/common/http';
#Injectable()
export class MapsService {
constructor(private http: HttpClient) { }
getMap(params) {
console.log('Service', params);
return this.http.get('/api/posts/' + params.id);
}
}
map.component.ts
Here, where I build the map with google in the future
import { Component, OnInit } from '#angular/core';
import {MapsService} from '../maps.service';
import {ActivatedRoute} from '#angular/router';
import {MapPath} from '../map-path';
#Component({
selector: 'app-maps',
templateUrl: './maps.component.html',
styleUrls: ['./maps.component.css']
})
export class MapsComponent implements OnInit {
results: any;
params: {};
test: any;
constructor(
private mapsService: MapsService,
private route: ActivatedRoute,
) { }
ngOnInit() {
this.route.params.subscribe( params => {
this.params = params;
});
this.mapsService.getMap(this.params).subscribe(
data => {
this.results = data;
this.test = new MapPath(data, 'test');
},
err => {
console.log('Error occured', err);
});
console.log('this.test', this.test.getX());
console.log('this.results', this.results);
}
}
map-path.ts
Here get the different properties from geoJSON
export class MapPath {
test: string;
constructor(path: any, test: string) {
this.test = test;
console.log('Path', path);
console.log('test', test);
}
getX() {
return this.test;
}
}
Thanks.
Your problem is that Observables are async functions, meaning your subscription callback will happen later than the console.log calls following your this.mapsService.getMap call.
This is guaranteed by async nature of Observables.
You can either move your console logs inside of the subscribe function or create another subscription.
Hope this helps.

Angular 2 Interface throwing error of non existing property

I have an Angular 2 interface books.ts
export interface Books {
artists: Object;
tracks: Object;
}
This is the my service file where I am using it with http request searchService.ts
import { Injectable } from '#angular/core';
import { Http, Response, Headers, RequestOptions } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import { Books } from 'app/pages/search-results/books';
import 'rxjs/add/operator/map'
#Injectable()
export class SearchService {
constructor(private _http:Http) { }
getBook(keyword): Observable<Books[]>{
return this._http.get('https://api.spotify.com/v1/search?q=' + keyword + '&type=track,artist')
.map((response: Response) => <Books[]> response.json());
}
}
And this is my component where I am using interface searchResults.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { SearchService } from 'app/shared/search/search.service';
import { Books } from 'app/pages/search-results/books';
#Component({
selector: 'app-search-results',
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.css'],
providers: [SearchService]
})
export class SearchResultsComponent implements OnInit {
keyword: any;
sub: any;
books: Books[];
errMessage: string;
arists: Object;
constructor(private _route: ActivatedRoute, private _router: Router, private _search: SearchService) { }
ngOnInit() {
this.sub = this._route
.queryParams
.subscribe(params => {
// Defaults to 0 if no query param provided.
this.keyword = params['keyword'] || 0;
this.getBooks(this.keyword);
});
//
}
getBooks(value) {
this._search.getBook(value)
.subscribe(
res => {
this.books = res;
console.log(res.artists);
},
error => { this.errMessage = <any>error }
);
}
}
The error comes when I try to console the res.artists. The error says Property 'artists' does not exist on type 'Books[]'. I am new to Angular 2 and doesn't know how to fix that.
The response is looks like
{artists:{limit: 20, item:[]}, tracks:{limit: 20, item:[]}}
I'm not sure but I think you try to get res.artist from collection of books. You can check it by for or e.g res[0].artist to get concrete artist.
getBook function in class SearchService return an array of Books object (Books[])
so, the res in getBooks function in SearchResultsComponent will be an Array of Books.
You can console.log(res) to see detail, if you want access to artists please try with res[0].artists if the res is not an empty array
The problem is that I am getting Object in response and I am assigning it to an Array which is causing the error. I have simply changes the both types to object and it solved my problem.
From this
books: Books[];
To this
books: Books;

Categories

Resources