Issue when retrieving data from Firebase using ionic+angularfire2 - ionic-framework

I am following a tutorial to create a Chat application using Ionic and AngularFire2.
However, I am having this error when I am trying to retrieve data from Firebase Database.
TypeError: Object(...) is not a function
at SwitchMapSubscriber.project (http://localhost:8100/build/vendor.js:74005:76)
at SwitchMapSubscriber._next (http://localhost:8100/build/vendor.js:62295:27)
at SwitchMapSubscriber.Subscriber.next (http://localhost:8100/build/vendor.js:20750:18)
at RefCountSubscriber.Subscriber._next (http://localhost:8100/build/vendor.js:20786:26)
at RefCountSubscriber.Subscriber.next (http://localhost:8100/build/vendor.js:20750:18)
at Subject.next (http://localhost:8100/build/vendor.js:23237:25)
at ConnectableSubscriber.Subscriber._next (http://localhost:8100/build/vendor.js:20786:26)
at ConnectableSubscriber.Subscriber.next (http://localhost:8100/build/vendor.js:20750:18)
at Notification.observe (http://localhost:8100/build/vendor.js:51893:50)
at AsyncAction.DelaySubscriber.dispatch (http://localhost:8100/build/vendor.js:76316:40)
My Chat.TS code
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { AngularFireDatabase} from 'angularfire2/database';
import { Observable } from 'rxjs/Observable';
/**
* Generated class for the ChatPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-chat',
templateUrl: 'chat.html',
})
export class ChatPage {
username: string = '';
message : string = '';
//messages : object[] = [];
items: Observable<any[]>;
constructor(public db: AngularFireDatabase , public navCtrl: NavController, public navParams: NavParams) {
console.log(this.navParams);
this.username = this.navParams.get('username');
this.items = db.list('chat').valueChanges();
}
ionViewDidLoad() {
console.log('ionViewDidLoad ChatPage');
}
sendMessage(){
this.db.list('/chat').push({
username:this.username,
message:this.message
});
}
}
My Chat.HTML code
<ion-header>
<ion-navbar>
<ion-title>Chat</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ul>
<li *ngFor="let item of items | async">
{{ item | json }}
</li>
</ul>
</ion-content>
<ion-footer>
<ion-toolbar>
<ion-input type="text" [(ngModel)]="message"></ion-input>
<button ion-button icon-only (click)="sendMessage()"><ion-icon name="send"></ion-icon>
</button>
</ion-toolbar>
</ion-footer>
I had tried many different ways of doing it and I still get the same object error.
Anyone have any idea what is causing this error?
Thanks for your help.

Related

Ionic Framework 3 Error: Window Redirect Problems

I'm new in Ionic Framework, and I'm using version 3 to build a simple application that redirects the user to an .html page after logging in. I've edited the home.ts file to make the log in possible, and I've built a test .html called index.html, in the folder "pages/home" inside the ionic project, but I'm getting an error when I try to conned the "submit" button to this index.html page:
Code in home.html
<ion-header>
<ion-navbar>
<ion-title>
Login
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list no-lines>
<ion-item>
<ion-label floating>User</ion-label>
<ion-input type="text" [(ngModel)]="username"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Senha</ion-label>
<ion-input type="text" [(ngModel)]="password"></ion-input>
</ion-item>
<button block ion-button block (click)="signIn()">Sign in</button>
</ion-list>
</ion-content>
Code in home.ts
import { Component } from '#angular/core';
import { NavController, AlertController, IonicPage } from 'ionic-angular';
import { index } from 'c:/Ionic/task-1/src/pages/home/index.html';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public username : any = '';
public password : any = '';
constructor(public navCtrl: NavController, public alertCtrl: AlertController)
{
}
signIn() {
this.navCtrl.push('index.html');
}
}
The code in index.html
<ion-header>
<ion-navbar>
<ion-title>
Login
</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p>Testing HTML page redirect</p>
</ion-list>
</ion-content>
The error: https://i.stack.imgur.com/vRivh.png
What could I do?
In ionic 3 you can navigate through pages using NavController.You should create a component that you want to route.
For that you have to import the component(page)
HTML file
<button block ion-button block (click)="signIn()">Sign in</button>
TS file
import { NavController } from 'ionic-angular';
import { StartPage } from './start-page';
#Component(
selector: 'app-home',
templateUrl: 'home.html'
})
class HomePage {
constructor(public navCtrl: NavController){}
signIn() {
this.navCtrl.push(StartPage);
}
}
Refer NavController documentation in ionic
check here
In home.ts file :
import { Component } from '#angular/core';
import { NavController, AlertController, IonicPage } from 'ionic-angular';
import { IndexPage} from '../index/index';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public username : any = '';
public password : any = '';
constructor(public navCtrl: NavController, public alertCtrl: AlertController){}
signIn() {
this.navCtrl.push(IndexPage);
}
}

Ionic 4 background blinks and tap delay

This is my first application using ionic4 and there is something weird happening. When I tap on any link, there is delay and the entire background blinks before it loads the page. Here is a video showing this weird behave: https://youtu.be/NqoOMQYyr4k
For reference, here is the code for the pages:
On the global.scss i have this property to setup the background
ion-content {
--background: #000 url('./assets/images/main-bg.png') no-repeat center center / cover;
}
news.page.ts
import { News } from './news.model';
import { Component, OnInit } from '#angular/core';
import { NewsService } from '../services/news.service';
import { Router } from '#angular/router';
import { NavController } from '#ionic/angular';
#Component({
selector: 'app-news',
templateUrl: './news.page.html',
styleUrls: ['./news.page.scss'],
})
export class NewsPage implements OnInit {
news: any;
constructor(private newsService: NewsService, private router: Router, private navController: NavController) { }
ngOnInit() {
this.news = this.newsService.getAllEvents();
}
go(id: string) {
this.navController.navigateForward('news/' + id);
}
}
news.page.html
<ion-header>
<ion-toolbar color="grey">
<ion-buttons slot="start">
<ion-menu-button></ion-menu-button>
</ion-buttons>
<ion-title style="color: #524A4A!important">News</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-grid padding class="margin-logo-header">
<ion-row>
<div>
<h2>Noticias HD Friends</h2>
</div>
</ion-row>
</ion-grid>
<ion-card color="grey" *ngFor="let news of news | async">
<ion-nav-pop (click)="go(news.id)" >
<ion-img src="{{news.picture}}"></ion-img>
<ion-card-header>
<ion-card-title>{{ news.title }}</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>{{ news.subtitle }}</p>
</ion-card-content>
</ion-nav-pop>
</ion-card>
</ion-content>
news.service.ts
import { Injectable } from '#angular/core';
import { AngularFireDatabase, AngularFireList } from '#angular/fire/database';
import { News } from '../news/news.model';
#Injectable({
providedIn: 'root'
})
export class NewsService {
NODE = 'news/';
news: AngularFireList<News[]>;
constructor(private db: AngularFireDatabase) { }
getAllEvents() {
const localNews = this.db.list(this.NODE);
return localNews.valueChanges();
}
getNews(id: string) {
return this.db.object(this.NODE + id);
}
}
Is this a bug because it's a beta or is this something I messed up?
Thanks guys
UPDATE 1
This seems to be a bug on ionic framework. As soon as I get something I'll post here for future reference.

Ionic 3: ion- auto-complete - How to pass different data other than autocomplete generated data

I have created an auto complete functionality in ionic 3 framework.
app.component.html
<form [formGroup]="myForm" (ngSubmit)="openModal()">
<div class="ion-form-group">
<ion-auto-complete [dataProvider]="ionAutoCompleteService"
[options]="{ placeholder : 'Search an Institution' }" formControlName="institution"
required>
</ion-auto-complete>
</div>
<button [disabled]="!myForm.valid" icon-left ion-button type="submit" block>
<ion-icon name="link"></ion-icon>
Link Institution
</button>
</form>
for this I also create the service provider as follow
import {AutoCompleteService} from 'ionic2-auto-complete';
import { Http } from '#angular/http';
import {Injectable} from "#angular/core";
import 'rxjs/add/operator/map'
#Injectable()
export class IonicAutoCompleteService implements AutoCompleteService {
labelAttribute = "name";
constructor(private http:Http) {
}
getResults(keyword:string) {
return this.http.get("https://aqueous-oasis-93790.herokuapp.com/institutions/search?name="+keyword)
.map(
result =>
{
console.log(result)
return result.json().institutions
.filter(item => item.name.toLowerCase().startsWith(keyword.toLowerCase()) )
});
}
}
this service provides me the name of institutions which are retrieve from the json file.
To access this service I just need to import the service in app.component.ts file
app.component.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ModalController } from 'ionic-angular';
import { FormGroup, FormControl, Validators } from '#angular/forms';
import { IonicAutoCompleteService } from '../../../services/ionic-autocomplete.service';
import { AddAccountModalPage } from './add-account-modal/add-account-modal';
#IonicPage()
#Component({
selector: 'page-add-account',
templateUrl: 'add-account.html',
})
export class AddAccountPage {
constructor(public navCtrl: NavController, public navParams: NavParams,
public ionAutoCompleteService:IonicAutoCompleteService,
public modalCtrl:ModalController) {
}
ngOnInit(): void { }
myForm = new FormGroup({
institution: new FormControl('', [Validators.required])
})
submit(): void {
console.log(this.myForm.value.institution)
}
onClick() {
console.log("img clicked")
}
openModal() {
let modal = this.modalCtrl.create(AddAccountModalPage);
modal.present();
}
}
My question is that, When I am submit the form, the value in search box will be submitted which is name of institution.
I want to send the institution name to following ionic modal
I also want to send institution id as a modal parameter like (ngSubmit)="openmodal(institution_id)" in app.component.html file
modal.html
<ion-header>
<ion-toolbar>
<ion-title>
Add Account Modal
</ion-title>
<ion-buttons start>
<button ion-button (click)="dismiss()">
<span ion-text color="primary" showWhen="ios">Cancel</span>
<ion-icon name="md-close" showWhen="android,windows"></ion-icon>
</button>
</ion-buttons>
</ion-toolbar>
</ion-header>
modal.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ViewController } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-add-account-modal',
templateUrl: 'add-account-modal.html',
})
export class AddAccountModalPage {
institution = "india"
constructor(public navCtrl: NavController, public navParams: NavParams,
public viewCtrl: ViewController) {
}
ionViewDidLoad() {
}
dismiss() {
this.viewCtrl.dismiss();
}
}
You can send parameters like this:
openModal() {
let Modal = this.modalCtrl.create(AddAccountModalPage,
{ institution: this.formGroup.get('institution').value
});
Modal.present();
}
and after get this parameter in modal.ts:
institution: any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController) {
}
ngOnInit() {
this.institution= this.navParams.get('institution');
}

Ionic Http request re-occurring multiple times

I'm learning Ionic and stuck on an issue. My app is stuck in a loop in which it is repeatedly fetching information from a remote server and causing the browser and crash.
I setup a service, code below, to retrieve the data:
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
/*
Generated class for the CategoriesServiceProvider provider.
See https://angular.io/guide/dependency-injection for more info on providers
and Angular DI.
*/
#Injectable()
export class CategoriesServiceProvider {
apiURL = 'https://reqres.in/api/users';
constructor(public http: HttpClient) {
console.log('Hello CategoriesServiceProvider Provider');
}
getUsers(){
return new Promise(resolve => {
this.http.get(this.apiURL).subscribe(data => {
resolve(data);
// console.log(data);
}, err => {
console.error(err);
});
});
}
}
Below is the code in my categories.ts file which uses the service above:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { CategoriesServiceProvider } from '../../providers/categories-service/categories-service';
/**
* Generated class for the CategoriesPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-categories',
templateUrl: 'categories.html',
providers: [CategoriesServiceProvider]
})
export class CategoriesPage {
constructor(public navCtrl: NavController, public navParams: NavParams, private categories: CategoriesServiceProvider) {
}
users: any;
getUsers(){
this.categories.getUsers().then(data => {
this.users = data;
console.log(this.users);
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad CategoriesPage');
this.getUsers();
}
}
... followed by categories.html:
<ion-header>
<ion-navbar>
<ion-title>categories</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item *ngFor="let user of getUsers()">
TESTING - {{user.gender}}
</ion-item>
</ion-list>
</ion-content>
I don't know why the http request is repeating instead of fetching once and then going away.
here you are looping on the function to get your data:
<ion-content padding>
<ion-list>
<ion-item *ngFor="let user of getUsers()">
TESTING - {{user.gender}}
</ion-item>
</ion-list>
</ion-content>
Replace it with the retrieved data instead!
Something like :
<ion-content padding>
<ion-list>
<ion-item *ngFor="let user of this.users">
TESTING - {{user.gender}}
</ion-item>
</ion-list>
</ion-content>

How do I in ionic 2 pass data from a modal with a form on, to the home page?

Hi there can anyone help out. I am new to Ionic and Angular. I am trying to create a weather app in Ionic 2.
I have created a Home page with a Click event calling an AddWeather() function.
The function opens up a modal with a form attached. I am trying to pass data from the form on the modal back to the home page an output on the screen. I have tried ngModel but can't seem to get it working correctly.
Here is my Code: (home.ts)
import { Component } from '#angular/core';
import { NavController, ModalController, NavParams } from 'ionic-angular';
import { AddPage } from '../add/add';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public weatherList = [];
constructor(public navCtrl: NavController, public modalCtrl: ModalController) {
}
addWeather() {
let addWeatherModal = this.modalCtrl.create(AddPage);
addWeatherModal.present();
}
}
(add.html)
<ion-header>
<ion-navbar color="weatherbru">
<ion-title>Modal</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="CloseModal()"><ion-icon name="close"></ion-icon></button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<form>
<ion-item>
<ion-label stacked>City</ion-label>
<ion-input type="text" ></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Country</ion-label>
<ion-select >
<ion-option value="us">United States</ion-option>
<ion-option value="uk">United Kingdom</ion-option>
</ion-select>
</ion-item>
<button ion-button block (click)="CloseModal()">Add Weather</button>
</form>
<div padding>
</div>
</ion-content>
(add.ts)
import { Component } from '#angular/core';
import { ModalController } from 'ionic-angular';
import { NavController, NavParams, ViewController } from 'ionic-angular';
#Component({
selector: 'page-add',
templateUrl: 'add.html'
})
export class AddPage {
constructor(public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams) {}
CloseModal() {
this.viewCtrl.dismiss();
}
}
In your html :
<form>
<ion-item>
<ion-label stacked>City</ion-label>
<ion-input [(ngModel)]="form.city" type="text" ></ion-input>
</ion-item>
<ion-item>
<ion-label stacked>Country</ion-label>
<ion-select [(ngModel)]="form.country">
<ion-option value="us">United States</ion-option>
<ion-option value="uk">United Kingdom</ion-option>
</ion-select>
</ion-item>
<button ion-button block (click)="CloseModal()">Add Weather</button>
</form>
In your add.ts file :
export class AddPage {
form : any; //Declare the form object to be bound to your html
constructor(public viewCtrl: ViewController, public navCtrl: NavController, public navParams: NavParams) {}
CloseModal() {
this.viewCtrl.dismiss(this.form); //Send back the form object when closeModal is called
}
}
In your home.ts :
addWeather() {
let addWeatherModal = this.modalCtrl.create(AddPage);
addWeatherModal.present();
addWeatherModal.onDidDismiss(data=>{ //This is a listener which wil get the data passed from modal when the modal's view controller is dismissed
console.log("Data =>", data) //This will log the form entered by user in add modal.
})
}