I have small problem with my chat page :) wanted to do some chat application
I have login that is working but when I click to button chat it's crashing. I am beginner so maybe I can't see correctly. It's in Ionic 3
Home.ts
import { Component } from '#angular/core';
import { NavController, IonicPage } from 'ionic-angular';
import { Auth } from '#ionic/cloud-angular';
import { User } from '#ionic/cloud-angular';
import { LoginPage } from '../login/login';
import { About } from '../about/about';
import { ChatPage } from '../chat/chat';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController, public auth: Auth, public user: User) {
console.log(user);
}
logout() {
this.auth.logout();
this.navCtrl.setRoot(LoginPage);
}
about(){
this.navCtrl.setRoot(About);
this.navCtrl.push(About);
}
chat(){
this.navCtrl.setRoot(ChatPage);
this.navCtrl.push(ChatPage);
}
}
home.html
<ion-header>
<ion-navbar>
<ion-title>
Home
</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="logout()">
<ion-icon name="exit"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<h2>Welcome back, {{ user.details.name }}</h2>
<p>
<button ion-button color="secondary" block>Something</button>
</p>
<p>
<button ion-button color="secondary" block (click)="chatPage()">Chat</button>
</p>
<p>
<button ion-button color="secondary" block (click)="about()">About</button>
</p>
</ion-content>
chat.ts
import { Component, NgZone, ViewChild } from '#angular/core';
import { NavController, Content } from 'ionic-angular';
import { Validators, FormBuilder } from '#angular/forms';
import * as io from 'socket.io-client';
import { HomePage } from '../home/home';
#Component({
selector: 'page-chat',
templateUrl: 'chat.html'
})
export class ChatPage {
public chatForm: any;
#ViewChild(Content) content: Content;
messages:any = [];
socketHost: string = "http://localhost:3000/";
socket:any;
chat:any;
username:string;
zone:any;
chatField: any;
constructor(public navCtrl: NavController, private fb: FormBuilder){
this.socket = io.content(this.socketHost);
this.zone = new NgZone({enableLongStackTrace: false});
this.socket.on("chat me", (msg) =>{
this.zone.run (() =>{
this.messages.push(msg);
this.content.scrollToBottom();
});
});
this.chatForm = fb.group({
'chatField': ['', Validators.compose([Validators.required])],
});
this.chatField = this.chatForm.controls['chatField'];
}
chatSend(v) {
let data = {
message: v.chatText,
username: this.username
}
this.socket.emit('new message', data);
this.chat = "";
}
onSubmit(value: string): void {
if(this.chatForm.valid) {
}
}
}
chat.html
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Chat</ion-title>
</ion-navbar>
<ion-input [(ngModel)] = "username" placeholder="Username"> </ion-input>
</ion-header>
<ion-content class="chat">
<ion-list>
<div *ngFor="let data of messages">
<ion-item *ngIf="username === data.username" style="border-right: solid 5px red;">
<p class="chat-text" item-left>
<strong> {{data.username}}: </strong>
{{data.message}}
</p>
<p class="chat-time" item-right>
{{data.date | date:'dd/MM/yyyy'}}
</p>
</ion-item>
<ion-item *ngIf="username !== data.username" style="border-right: solid 5px green;">
<p class="chat-text" item-left>
<strong> {{data.username}}: </strong>
{{data.message}}
</p>
<p class="chat-time" item-right>
{{data.date | date:'dd/MM/yyyy'}}
</p>
</ion-item>
</div>
</ion-list>
</ion-content>
<ion-footer>
<form padding [formGroup]="chatForm" (ngSubmit)="onSubmit(chatForm.value)">
<ion-item>
<ion-input [(ngModel)]="chatField" name="chatText" required placeholder="type here....."></ion-input>
</ion-item>
<br/><br/>
<button type="submit" ion-button [disabled]="!chatForm.valid" block>Send</button>
</form>
</ion-footer>
the error that I am getting is
Runtime Error
co.chatPage is not a function
Stack
TypeError: co.chatPage is not a function
at Object.eval [as handleEvent] (ng:///AppModule/HomePage.ngfactory.js:290:24)
at handleEvent (http://localhost:8100/build/main.js:12302:138)
at callWithDebugContext (http://localhost:8100/build/main.js:13510:42)
at Object.debugHandleEvent [as handleEvent] (http://localhost:8100/build/main.js:13098:12)
at dispatchEvent (http://localhost:8100/build/main.js:9277:21)
at http://localhost:8100/build/main.js:9867:38
at HTMLButtonElement.<anonymous> (http://localhost:8100/build/main.js:35897:53)
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:12256)
at Object.onInvokeTask (http://localhost:8100/build/main.js:4613:37)
at t.invokeTask (http://localhost:8100/build/polyfills.js:3:12177)
at n.runTask (http://localhost:8100/build/polyfills.js:3:7153)
at HTMLButtonElement.invoke (http://localhost:8100/build/polyfills.js:3:13213)
Ionic Framework: 3.1.1
Ionic App Scripts: 1.3.7
Angular Core: 4.0.2
Angular Compiler CLI: 4.0.2
Node: 7.2.0
OS Platform: Windows 10
Navigator Platform: Win32
User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) App
The problem is you have called (click)="chatPage()" in your template and the function in your HomePage.ts is chat().
Do:
<button ion-button color="secondary" block (click)="chat()">Chat</button>
Side Note:
You dont have to do both push and setRoot.
setRoot will create an new navigation stack and set the particular page as Root.
push will push the page onto the current navigation stack.
Use one of them based on your requirement.
Related
Just tried making a Training plans page where the user can add his own plans .
tried using firebase but it doesnt work really well..
After I made my first plan and enter the contirbutes of name and the exercise type (Muscle) it just threw me out and showed me that :
I get this ERROR:
ERROR TypeError: Cannot read property 'name' of undefined
at Object.eval [as updateRenderer] (Plans.html:17)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:14376)
at checkAndUpdateView (core.js:13512)
at callViewAction (core.js:13857)
at execEmbeddedViewsAction (core.js:13815)
at checkAndUpdateView (core.js:13508)
at callViewAction (core.js:13857)
at execComponentViewsAction (core.js:13789)
at checkAndUpdateView (core.js:13513)
at callViewAction (core.js:13857)
here is the code by parts:
Plans.ts who supposed to the the data from the firebase and show it on the screen:
import { Plan } from './../../models/plan/plan.model';
import { Component } from '#angular/core';
import { NavController, NavParams } from 'ionic-angular';
import { IonicPage } from 'ionic-angular/navigation/ionic-page';
import { PlansListService } from './../../services/plans/plans-list.service';
import { Observable } from 'rxjs/Observable';
#IonicPage()
#Component({
selector: 'page-plans',
templateUrl: 'plans.html'
})
export class Plans {
planslist$: Observable<Plan[]>;
constructor(public navCtrl: NavController, public navParams: NavParams,
private plans: PlansListService) {
this.planslist$ = this.plans
.getPlansList()
.snapshotChanges()
.map(
changes => {
return changes.map(c => ({
key: c.payload.key,
...c.payload.val()
}))
}
)
}
}
Here is the Plans.html:
<ion-header>
<ion-navbar >
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Training plans</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-list-header>
Your Plans
</ion-list-header>
<div ion-item *ngFor="let plan of planslist$ | async">{{Plan.name}} </div>
</ion-list>
<ion-fab color="fab" bottom right class="fabPalcement">
<button ion-fab color="fab" navPush='AddPlan'>
<ion-icon name="add"></ion-icon>
</button>
</ion-fab>
</ion-content>
addplan.ts that supposed to take the data to the firebase by attaching the name and muscles to the
'name' and 'muscles' variables that I made on the model:
import { PlansListService } from './../../services/plans/plans-list.service';
import { Plan } from './../../models/plan/plan.model';
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
#IonicPage()
#Component({
selector: 'page-addplan',
templateUrl: 'addplan.html',
})
export class AddPlan {
constructor(public navCtrl: NavController, public navParams: NavParams,
private plans: PlansListService) {
}
Plan: Plan = {
name: ' ',
muscles: ' ',
}
addNewPlan(plan: Plan){
this.plans.addNewPlan(plan).then(ref => {
this.navCtrl.setRoot('Plans', {key : ref.key})
})
}
}
addplan.html:
<ion-header>
<ion-navbar>
<ion-title>הוסף תוכנית אימונים</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding dir = "rtl">
<ion-item>
<ion-label>שם התוכנית</ion-label>
<ion-input [(ngModel)]="Plan.name" placeholder="התוכנית שלי" item-end></ion-input>
</ion-item>
<ion-item>
<ion-label>קבוצת שרירים</ion-label>
<ion-select [(ngModel)]="Plan.muscles">
<ion-option value="c">חזה</ion-option>
</ion-select>
</ion-item>
<button ion-button (click)="addNewPlan(Plan)">הוסף</button>
</ion-content>
What can I do? where is the problem?? :(
I am completely new to Ionic as of last night and I've created a blank project and now stupidly realized that I'd like to have a side menu in there. So I've followed a couple of online tutorials to add one in, but no matter what I try I can get the menu to show when I click the menu toggle icon button.
Here's what I've added in to try and make this work:
app.html
<ion-menu side="right" [content]="content">
<ion-content>
<ion-list>
<button>Page 1</button>
<button>Page 2</button>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav #content [root]="rootPage" swipeBackEnabled="false"></ion-nav>
app.component.ts:
import { Component, ViewChild } from '#angular/core';
import { Platform, Nav } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { HomePage } from '../pages/home/home';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = HomePage;
#ViewChild(Nav) nav: Nav;
constructor(platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
});
}
}
home-logged-in.html:
<ion-header>
<ion-navbar color='primary'>
<button ion-button menu-toggle>
<ion-icon name="menu"></ion-icon>
</button>
</ion-navbar>
</ion-header>
<ion-content padding>
</ion-content>
Wrong attribute. Replace:
<button ion-button menu-toggle>
With:
<button ion-button menuToggle>
I want to show a list of the bluetooth devices present around in Ionic2.
I made .ts and .html page in Ionic.
Now I can turn on bluetooth on my phone using the app, but can't see other devices.
.ts file:
import { Component } from '#angular/core';
import { Platform, AlertController } from 'ionic-angular';
import { BluetoothSerial } from 'ionic-native';
import { NavController } from 'ionic-angular';
#Component({
selector: 'page-page1',
templateUrl: 'page1.html'
})
export class Page1 {
public working:string;
public var2: string ;
public lists = [];
constructor(private alertCtrl: AlertController, public platform: Platform, public navCtrl: NavController) {
platform.ready().then(() => {
BluetoothSerial.isConnected()
.then(() => {
console.log('is connected');
}, (err) => {
console.log(' not connected')
})
});
}
enableBluetooth(){
BluetoothSerial.enable()
}
discoverBluetooth(){
/* BluetoothSerial.setDeviceDiscoveredListener(function(device) {
console.log('Found: '+device.id);
});*/
}
unpairedBluetooth(){
BluetoothSerial.discoverUnpaired().then(function(devices) {
devices.forEach(function(device) {
console.log(device.id)
});
})
}
listDevices(){
BluetoothSerial.isEnabled().then((data)=> {
console.log(data);
BluetoothSerial.list().then((allDevices) => {
this.lists = allDevices;
let result = [];
for (var out in this.lists) {
result.push(out);
}
})
})
}}
.html file:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Page One</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-buttons>
<button ion-button (click) = "enableBluetooth()">Turn on bluetooth</button>
</ion-buttons>
<ion-buttons>
<button ion-button (click) = "listDevices()">List devices</button>
</ion-buttons>
<ion-list>
<ion-item *ngFor="let out of lists">{{out}}</ion-item>
</ion-list>
<ion-buttons>
<button ion-button (click) = "unpairedBluetooth()">Unpair</button>
</ion-buttons>
</ion-content>
I have response in my application but it only shows:
[object Object]
How can I read these?
i think in this line :
<ion-item *ngFor="let out of lists">{{out}}</ion-item>
change {{out}} to something like {{out.name}} , out is complex object but you should display key of object. if you want where name is come check this Bluetooth Serial
[{
"class": 276,
"id": "10:BF:48:CB:00:00",
"address": "10:BF:48:CB:00:00",
"name": "Nexus 7"
}]
I am using a project to get some user data from Firebase. I want to put that data into a "Profile page". Everything works except for one problem. The data doesn't show on the html page until I click on an item in the page, like to edit some data for example. The data will also show if I click back, then reenter the page. So it's like the data loads the blank template, but never updates it once the data from Facebook is received. Any suggestions? Here is some of the code from the page.
profile.html
<ion-header>
<ion-navbar color="primary">
<ion-title>Profile</ion-title>
<ion-buttons end>
<button ion-button item-left icon-right (click)="logOut()">
<ion-icon name=""></ion-icon>
Logout
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-list-header>
Personal Information
</ion-list-header>
<ion-item (click)="updateName()">
<ion-grid>
<ion-row>
<ion-col width-50>
Name
</ion-col>
<ion-col *ngIf="userProfile?.firstName || userProfile?.lastName">
{{userProfile?.firstName}} {{userProfile?.lastName}}
</ion-col>
<ion-col class="placeholder-profile" *ngIf="!userProfile?.firstName">
<span>
Tap here to edit.
</span>
</ion-col>
</ion-row>
</ion-grid>
</ion-item>
<ion-item>
<ion-label class="dob-label">Date of Birth</ion-label>
<ion-datetime displayFormat="MMM D, YYYY" pickerFormat="D MMM YYYY"
[(ngModel)]="birthDate" (ionChange)="updateDOB(birthDate)"></ion-datetime>
</ion-item>
<ion-item (click)="updateEmail()">
<ion-grid>
<ion-row>
<ion-col width-50>
Email
</ion-col>
<ion-col width-50 *ngIf="userProfile?.email">
{{userProfile?.email}}
</ion-col>
<ion-col class="placeholder-profile" *ngIf="!userProfile?.email">
<span>
Tap here to edit.
</span>
</ion-col>
</ion-row>
</ion-grid>
</ion-item>
<ion-item (click)="updatePassword()">
<ion-grid>
<ion-row>
<ion-col width-50>
Password
</ion-col>
<ion-col class="placeholder-profile">
<span>
Tap here to edit.
</span>
</ion-col>
</ion-row>
</ion-grid>
</ion-item>
</ion-list>
</ion-content>
Here is the code from the profile.ts page
import { NavController, AlertController } from 'ionic-angular';
import { Component } from '#angular/core';
import { ProfileData } from '../../providers/profile-data';
import { AuthData } from '../../providers/auth-data';
import { LoginPage } from '../login/login';
#Component({
selector: 'page-profile',
templateUrl: 'profile.html',
})
export class ProfilePage {
public userProfile: any;
public birthDate: string;
zone: NgZone;
constructor(public navCtrl: NavController, public profileData: ProfileData,
public authData: AuthData, public alertCtrl: AlertController) {
}
ionViewDidEnter(){
this.profileData.getUserProfile().on('value', (data) => {
this.userProfile = data.val();
this.birthDate = this.userProfile.birthDate;
});
}
I also tried wrapping it in an NgZone object as suggested by others, which looks like this:
import { NavController, AlertController } from 'ionic-angular';
import { Component } from '#angular/core';
import { ProfileData } from '../../providers/profile-data';
import { AuthData } from '../../providers/auth-data';
import { LoginPage } from '../login/login';
import { NgZone } from '#angular/core';
#Component({
selector: 'page-profile',
templateUrl: 'profile.html',
})
export class ProfilePage {
public userProfile: any;
public birthDate: string;
zone: NgZone;
constructor(public navCtrl: NavController, public profileData: ProfileData,
public authData: AuthData, public alertCtrl: AlertController) {
this.zone = new NgZone({});
this.zone.run(() => {
//Your promise code
this.profileData.getUserProfile().on('value', (data) => {
this.userProfile = data.val();
this.birthDate = this.userProfile.birthDate;
});
});
}
None of this seems to work. The data is there, it just doesn't show until I click on an item/UI object, then it populates correctly. Help!
You have to do it like below.Hope code is self-explanatory.If you have any question, please comment below.
How to install Angularfire2?
ProfileData.ts
import { AngularFire, FirebaseListObservable, FirebaseObjectObservable } from 'angularfire2';
#Injectable()
export class ProfileData {
constructor(public af: AngularFire) {}
getUserProfile(data: string): FirebaseObjectObservable<any> {
return this.af.database.object(`path-to-your-firebase-object`);
}
}
YourComponent.ts
public profile: any;
constructor(public profileData: ProfileData) {
this.profileData.getUserProfile(your-user-id).subscribe(profileSnap => {
this.profile= profileSnap ;
});
}
I'm having an issue in my ionic2/angular2 app.
I'm building a quizz app, in which the user is prompted to answer questions, on radio choices.
The moment the first choice is made, I get this error:
EXCEPTION: Attempt to use a dehydrated detector: QuizzPage_2 -> select
The console:
The code breaks here when I debug Pause On Exception:
SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) {
try {
fn.call(this._context, value);
}
catch (err) {
this.unsubscribe();
throw err;
Here are my main files:
The page.html:
(...)
<ion-item radio-group *ngFor="#choice of quizz.getChoices()">
<ion-label>
<p courant>{{ choice }}</p>
</ion-label>
<ion-radio (click)="onSubmit($event, choice)">
{{ choice }}
</ion-radio>
</ion-item>
(...)
My page.ts:
import {Page, NavController, NavParams} from 'ionic-angular';
import {Quizz} from '../models/quizz';
import {QuizzResultsPage} from './quizz-results.page';
import quizzes from '../../data/quizzes';
#Page({
templateUrl: 'build/pages/quizz/Quizzes/templates/quizz.page.html',
})
export class QuizzPage {
nav;
quizz;
constructor(nav: NavController, params: NavParams) {
this.nav = nav;
// Load the quizz with passed topicId from the params.get (import{NavParams})
this.quizz = this.loadQuizz(params.get('topicId'));
}
loadQuizz(topicId) {
// cont quizz = data (import quizzes from '../../data/quizzes';)
const quizz = quizzes.filter((quizz) => {
return quizz.topicId === topicId;
})[0];
return new Quizz(quizz);
}
onSubmit(event, answer) {
this.quizz.submitAnswer(answer);
if (this.quizz.isCompleted) {
this.nav.push(QuizzResultsPage, {
quizz: this.quizz
});
}
}
}
I'm still able to finish the quizz, but in the end in my result page, I can't go back or restart the quizz, and my navbar breaks...
My resultpage.html:
(...)
<ion-card-content>
<p>
Votre score:
<span primary>{{ quizz.getScore() }}</span> / <b>{{ quizz.getGradingScale() }}</b>
</p>
</ion-card-content>
</ion-card>
<!-- Questions with answers -->
<div [hidden]="quizz.isPerfect()">
<ion-card *ngFor="#i of quizz.items" style="background-color:aliceblue;">
<ion-card-header>
<b bluegray text-uppercase>Question: </b>
<p>
{{ i.question }}
</p>
</ion-card-header>
<ion-card-content>
<b bluegray text-uppercase>Réponse:</b>
<p courant text-justify>{{ i.answer }}</p>
</ion-card-content>
</ion-card>
</div>
<!-- Exit & Restart -->
<div padding style="width:70%; margin: 0 auto">
<button item-right block (click)="onHomeClicked($event)">Recommencer
<ion-icon name="refresh-circle"></ion-icon>
</button>
<button itel-left block (click)="onGoHome($event)">Accueil
<ion-icon name="home"></ion-icon>
</button>
</div>
</ion-content>
And finally my results.ts:
import {Page, NavController, NavParams} from 'ionic-angular';
import {TopicsPage} from '../../topics';
import {Home} from '../../../home/home';
#Page({
templateUrl: 'build/pages/quizz/Quizzes/templates/quizz-results.page.html',
})
export class QuizzResultsPage {
nav;
quizz;
constructor(nav: NavController, params: NavParams) {
this.quizz = params.get('quizz');
this.nav = nav;
this.nav.pop();
}
onHomeClicked(event) {
this.nav.setRoot(TopicsPage);
this.nav.pop(TopicsPage);
}
onGoHome(event){
this.nav.setRoot(Home);
this.nav.pop(Home);
}
Someone have an idea? Thanks