InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' at invalidPipeArgumentError - html

I want to get some data from database
Here is my service
export class CategoryService {
constructor(private db: AngularFireDatabase) { }
getCategories(){
return this.db.list('/categories');
}
$Component code
export class ProductFormComponent implements OnInit {
categories$;
constructor(categoryService: CategoryService) {
this.categories$ = categoryService.getCategories();
}
$here is my html
<div class="form-group">
<label for="category">Category</label>
<select id="category" class="form-control">
<option value=""> </option>
<option *ngFor="let c of categories$ | async" [value]="c.$key">
{{c.name}}
</option>
</select>
</div>

Firebase libraries return promises. Make them return observables.
import { from } from 'rxjs/operators';
export class CategoryService {
constructor(private db: AngularFireDatabase) { }
getCategories(){
return from(this.db.list('/categories'));
}

Try these code it should work
import {Injectable} from '#angular/core';
import {AngularFireDatabase} from '#angular/fire/database';
import {from} from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class CategoryService {
constructor(private db: AngularFireDatabase) {}
getCategories() {
return from(this.db.list('/categories').valueChanges());
}
}

Related

Angular autocomplete is not working MySQL API

we tried Autocomplete in angular using codeigniter3 controller as a api. but it not reflected in the angular home page.
Autoserivce.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root',
})
export class AutoService {
private baseURL = 'http://localhost/travelgate/api/item';
constructor(private http: HttpClient) {}
getData() {
return this.http.get(this.baseURL);
}
}
app.component.ts
import { Component, OnInit } from '#angular/core';
import { AutoService } from './auto.service';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
title = 'ng-auto-complete';
posts!: any;
name: any;
constructor(private service: AutoService) {}
ngOnInit() {
this.getAllData();
}
getAllData() {
this.service.getData().subscribe((res: any) => {
this.posts = res;
console.log(this.posts);
});
}
nameValue(name: any) {
this.name = name;
console.log(this.name);
}
}
app.Component.html
<div class="container">
<div class="row">
<div class="col-md-12">
<form class="form mt-5">
<label for="exampleDataList" class="form-label">Datalist example</label>
<input class="form-control" list="datalistOptions" id="exampleDataList" placeholder="Type to search..."
(change)="nameValue($any($event.target).value)">
<datalist id="datalistOptions">
<option *ngFor="let post of posts" [value]="post.name">
</datalist>
</form>
</div>
</div>
</div>
item.php
<?php
require APPPATH . 'libraries/REST_Controller.php';
class Item extends REST_Controller {
public function __construct() {
parent::__construct();
$this->load->database();
}
public function index_get($search = 0)
{
if(!empty($name)){
$this->db->select('*');
$this->db->from('rezlive_hotels_city_list');
$this->db->like('name', $name);
$data = $this->db->get()->result_array();
}else{
$query = $this->db->get("rezlive_hotels_city_list");
$resultList=$query->result_array();
$data= json_encode($resultList);
}
$this->response($data, REST_Controller::HTTP_OK);
}
}
screenshot

Angular: Dynamic creation of components in HTML doesn't work

I am able to dynamically create components:
import { Component, ComponentFactory, ComponentFactoryResolver, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '#angular/core';
import { FilterComponent } from '../filter/filter.component';
export enum FilterType {
DateRangeFilter, SensorSelectFilter
}
#Component({
selector: 'app-filter-collection',
templateUrl: './filter-collection.component.html',
styleUrls: ['./filter-collection.component.css']
})
export class FilterCollectionComponent implements OnInit {
filters: Array<ComponentRef<FilterComponent>> = [];
#ViewChild("messagecontainer", { read: ViewContainerRef }) entry!: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
onAddDateRangeFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.entry.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.DateRangeFilter;
this.filters.push(filter);
}
onAddSensorSelectFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.entry.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.SensorSelectFilter;
this.filters.push(filter);
}
ngOnInit(): void {
}
}
while FilterComponent looks like this:
#Component({
selector: 'app-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.css']
})
export class FilterComponent {
#Input() filter!: FilterType;
_FilterType = FilterType;
range = new FormGroup({
start: new FormControl(),
end: new FormControl()
});
constructor() {
}
ngOnInit(): void {
}
}
with this HTML:
<div *ngIf="filter === _FilterType.SensorSelectFilter">
<mat-form-field class="sensorFilter" appearance="fill">
<mat-label>Cars</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
</div>
<div *ngIf="filter === _FilterType.DateRangeFilter">
<mat-form-field class="dateFilter" appearance="fill">
<mat-label>Enter a date range to filter data</mat-label>
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
<input matStartDate formControlName="start" placeholder="Start date">
<input matEndDate formControlName="end" placeholder="End date">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
<mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error>
<mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error>
</mat-form-field>
</div>
However, I am not sure how to instantiate those components into HTML, I tried it like this in FilterCollectionComponent.html:
<div *ngFor="let filter of filters">
<app-filter [filter]="filter.instance.filter"></app-filter>
</div>
But this doesn't work.
Any ideas why? Any help is very much appreciated!
filter-collection.component.html:
<div #dynamicFilters></div>
filter-collection.component.ts
import { Component, ComponentFactory, ComponentFactoryResolver, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '#angular/core';
import { FilterComponent } from '../filter/filter.component';
export enum FilterType {
DateRangeFilter, SensorSelectFilter
}
#Component({
selector: 'app-filter-collection',
templateUrl: './filter-collection.component.html',
styleUrls: ['./filter-collection.component.css']
})
export class FilterCollectionComponent implements OnInit {
filters : Array<ComponentRef<FilterComponent>> = [];
#ViewChild('dynamicFilters', { read: ViewContainerRef }) dynamicInsert!: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
onAddDateRangeFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.dynamicInsert.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.DateRangeFilter;
this.filters.push(filter);
}
onAddSensorSelectFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.dynamicInsert.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.SensorSelectFilter;
this.filters.push(filter);
}
ngOnInit(): void {
}
}

How to get values from a list inside a JSON in Angular?

I need to get the values that are inside cities from this JSON, but i canĀ“t:
{
"id":0,
"department":"Amazonas",
"cities":["Leticia","Puerto Bayarta",]
},
{
"id":1,
"department":"Antioquia",
"cities":["Medellin","Bello",]
}
These are the components and services that I made:
cities.service.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root',
})
export class CitiesService {
constructor(private http: HttpClient) {}
getJSON(url: string) {
return this.http.get(url);
}
}
Component has an interface:
nueva-organizacion.component.ts
import { Component, OnInit } from '#angular/core';
import { CitiesService } from 'src/app/services/cities.service';
interface City{
department: string;
cities: string[];
}
#Component({
selector: 'app-nueva-organizacion',
templateUrl: './nueva-organizacion.component.html',
styleUrls: ['./nueva-organizacion.component.css'],
})
export class NuevaOrganizacionComponent implements OnInit {
public cities: City[] = [];
constructor(
public cities: CitiesService,
) {}
ngOnInit(): void {
this.cities
.getJSON(
'https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json'
)
.subscribe((res: any) => {
this.cities = res;
});
}
And finally, i would like to show the cities in a selector:
nueva-organizacion.component.html
<div class="form-input">
<select id="city" class="custom-select">
<option selected>Choose one...</option>
<option *ngFor="let city of cities">
{{ city.cities }}
</option>
</select>
</div>
I would like to get something like this in the selector:
Choose one...
Leticia
Puerto Bayarta
Medellin
Bello
But I get this:
Choose one...
Leticia, Puerto Bayarta
Medellin, Bello
Maybe the correct way is using the index {{ city.cities[] }} but I don't know how.
Please keep in mind that inside NuevaOrganizacionComponent you have to properties with the same name: 'cities', first the cities array and second the cities service.
Also I recommend you to use two selects instead of one, the first to select the department and the second to select the city.
The code will look like this:
nueva-organizacion.component.ts:
import { Component, OnInit } from '#angular/core';
import { CitiesService } from 'src/app/services/cities.service';
#Component({
selector: 'app-nueva-organizacion',
templateUrl: './nueva-organizacion.component.html',
styleUrls: ['./nueva-organizacion.component.css'],
})
export class NuevaOrganizacionComponent implements OnInit {
public departmentsArr = []
public departmentSelected:any = null;
public citySelected:any = null;
constructor(
public citiesServ: CitiesService,
) {}
ngOnInit(): void {
const urlCities = "https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json"
this.citiesServ.getJSON(urlCities)
.subscribe((res: any) => {
this.departmentsArr = res;
});
}
getCities(){
return this.departmentsArr.find(department => department.id == this.departmentSelected).ciudades
}
alertSelection(){
const departmentName = this.departmentsArr.find(department => department.id == this.departmentSelected).departamento;
const cityName = this.citySelected;
alert(`
You selected the department: ${departmentName} and the city: ${cityName}`)
}
}
nueva-organizacion.component.html
<div class="form-input">
<label for="departmentSelector">Select your department</label>
<select id="departmentSelected" class="custom-select" name="departmentSelector" [(ngModel)]="departmentSelected">
<option value="null">Choose one department...</option>
<option
*ngFor="let department of departmentsArr"
[value]="department.id">
{{ department.departamento }}
</option>
</select>
</div>
<div class="form-input" *ngIf="departmentSelected">
<label for="citySelector">Select your city</label>
<select id="citySelector" class="custom-select" name="citySelector" [(ngModel)]="citySelected">
<option selected>Choose one city...</option>
<option
*ngFor="let city of getCities()"
[value]="city">
{{ city }}
</option>
</select>
</div>
<button (click)="alertSelection()">WHAT WAS SELECTED?</button>
Also please verify FormsModule is imported into your app.module.ts or yourSubmodule.module.ts. This is important to enable the ([ngModule]) functionality.
import {FormsModule} from "#angular/forms";
// Other things
imports: [
// Other modules
FormsModule
],
ngOnInit(): void {
this.cities
.getJSON(
'https://raw.githubusercontent.com/marcovega/colombia-json/master/colombia.min.json'
)
.subscribe((res: any) => {
this.cities = [];
foreach(entry in res){
foreach(citi in entry.cities){
this.cities.push(citi);
}
}
});
}
On this side, you have an array of entries that has an array of cities inside. You need to flatten first all the cities inside ans, something like the code above. My code isn't exact but should give you an idea of what to write.

Angular: Fill Dropdown with Database

I'm new in coding and wanted to make a small Raid Planner.
Now I try to fill my Dropdown with the Raidnames from my database and could need some help with this step. I have problems with adding the data in a dropdownlist.
raid.service.ts
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import { RaidItem } from 'src/app/classes/raid-item';
import { environment } from './../environments/environment';
import { publishReplay, refCount } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class RaidService {
constructor(private httpClient: HttpClient) { }
private raidApiUrl = environment.webApiBaseUrl + '/api/Raid/';
getRaids(): Observable < RaidItem[] > {
return this.httpClient.get < RaidItem[] > (this.raidApiUrl + 'GetRaids').pipe(
publishReplay(1),
refCount());
}
}
raid.item.ts
export class RaidItem {
Id: number;
Name: string;
}
edit.component.ts
import { Component, OnInit } from '#angular/core';
import { NgbDateStruct, NgbCalendar } from '#ng-bootstrap/ng-bootstrap';
import { NgbDateStructAdapter } from '#ng-bootstrap/ng-bootstrap/datepicker/adapters/ngb-date-adapter';
import { NgbTimeStruct } from '#ng-bootstrap/ng-bootstrap';
import { RaidService } from 'src/services/raid.service';
import { RaidItem } from '../classes/raid-item';
#Component({
selector: 'app-edit',
templateUrl: './edit.component.html',
styleUrls: ['./edit.component.css']
})
export class EditComponent implements OnInit {
time = {hour: 13, minute: 30, second: 0};
hourStep = 1;
minuteStep = 15;
model: NgbDateStruct;
date: {year: number, month: number};
raidItems: RaidItem[] = [];
constructor(private calendar: NgbCalendar, private raidService: RaidService) { }
ngOnInit() {
this.raidService.getRaids().subscribe(raidResult => {
this.raidItems = raidResult;
});
}
selectToday() {
this.model = this.calendar.getToday();
}
onSubmit() {
}
}
edit.component.html
With this step I have the most problems. Don't know exactly how to get the raidnames into the dropdown
<div class="container1">
<ngb-datepicker #dp [(ngModel)]="model" (navigate)="date = $event.next"></ngb-datepicker>
</div>
<div class="container2">
<ngb-timepicker [(ngModel)]="time" [seconds]="false"
[hourStep]="hourStep" [minuteStep]="minuteStep" [secondStep]="00"></ngb-timepicker>
</div>
<select formControlName="raids" id="raids">
<option *ngFor="let RaidItem of getRaids(); let i = index" [value]="getRaids[i].Name">
{{getRaids[i].Name}}
</option>
</select>
You already stored your output in raidItems inside the compoent. SO don't need to call function from template. Use variable to construct the loop.
<option *ngFor="let raidItem of raidItems" [value]="raidItem.Name">
{{raidItem.Name}}
</option>
NgFor already provides alias to each iteration, which in your case is RaidItem. getRaids is a method, but you tried to use it like a variable.
This should work:
<select formControlName="raids" id="raids">
<option *ngFor="let RaidItem of getRaids(); let i = index" [value]="RaidItem.Id">
{{RaidItem.Name}}
</option>
</select>

Angular service not passing form data after routing

New to Angular and I feel like there's just an obvious mistake I am missing, code-wise.
I'm trying to follow the tutorial here: https://youtu.be/CUAHJxWGia0
I have one component to create/add an employee's ID called CreateEmployee.
On submission, it should route to a component to list all employees (ListEmployees).
It's using employee.service.ts.
When I click submit (before or without routing), it correctly logs the employee input to the console on CreateEmployee.
The problem is that when routing to the second component, ListEmployees, my new entry is not displayed at all, and only my test data is displayed.
I've made sure EmployeeService is included in my app.module as well.
create-employee.ts:
import { Component, OnInit } from '#angular/core'
import { FormControl, FormBuilder, NgForm } from '#angular/forms'
import { EmployeeService } from 'app/services/employee.service'
import { Router } from '#angular/router'
import { Employee } from 'app/shared/employee.model'
#Component({
selector: 'app-create-employee',
template: ` <form class="" [formGroup]="employeeForm" (ngSubmit)="saveEmployee()">
<div class="form-control">
<app-input
#memberID
name="memberID"
label="Member ID"
formControlName="memberID"
placeholder="Member ID"
></app-input>
</div>
<div><button type="submit" class="">Save</button></div>
</form>
{{ employeeForm.value | json }}
`,
styleUrls: ['./create-employee.component.scss'],
})
export class CreateEmployeeComponent implements OnInit {
employeeForm: any
constructor(private fb: FormBuilder, private _employeeService: EmployeeService, private _router: Router) {}
employee: Employee = {
memberID: null,
}
ngOnInit(): void {
this.employeeForm = this.fb.group({
memberID: new FormControl(''),
})
this.employee = this.employeeForm.get('memberID').value
}
saveEmployee() {
this._employeeService.save(this.employee)
console.log(this.employeeForm.get('memberID').value)
// this._router.navigate(['employee-list'])
}
}
list-employee.ts
import { Component, OnInit } from '#angular/core'
import { Employee } from 'app/shared/employee.model'
import { EmployeeService } from 'app/services/employee.service'
#Component({
selector: 'app-list-employees',
template: `<div *ngFor="let employee of employees">
<div class="">
{{ employee.memberID }}
</div>
</div> `,
styleUrls: ['./list-employees.component.scss'],
})
export class ListEmployeesComponent implements OnInit {
employees: Employee[] = []
constructor(private _employeeService: EmployeeService) {}
ngOnInit(): void {
this.employees = this._employeeService.getEmployees()
}
}
employee.service.ts
import { Injectable } from '#angular/core'
import { Employee } from 'app/shared/employee.model'
#Injectable({
providedIn: 'root',
})
export class EmployeeService {
listEmployees: Employee[] = [{ memberID: '1' }, { memberID: '2' }]
constructor() {}
getEmployees(): Employee[] {
return this.listEmployees
}
save(employee: Employee) {
this.listEmployees.push(employee)
}
}