Show specific data for the clicked element using popover - html

when I retrieve data from a json file, in the *ngFor displays all the values in the popover, but I need a specific popover to display based only on the data for selected/clicked weapon. Here is my code any help would be greatly appreciated. Thank you again for your help
Home
import { Component } from '#angular/core';
import { NavController, ViewController, PopoverController, Events} from 'ionic-angular';
import { RestProvider } from './../../providers/rest/rest';
import { PopupPage } from './../../pages/popup/popup';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
weapons: any;
errorMessage: string;
constructor(public navCtrl: NavController, public rest: RestProvider,
public popoverCtrl: PopoverController) {
}
ionViewDidLoad() {
this.getweapons();
}
getweapons() {
this.rest.getweapons()
.subscribe(
weapons => this.weapons = weapons,
error => this.errorMessage = <any>error);
}
presentPopover(myEvent)
{
let popover = this.popoverCtrl.create(PopupPage);
popover.present({
ev: myEvent
});
}
}
home.html
<ion-content>
<ion-searchbar [(ngModel)]="terms"></ion-searchbar>
<ion-item>
</ion-item>
<ion-list>
<button ion-item (click)="presentPopover($event)">
<ion-item *ngFor="let c of weapons?.weapon_category?.weapons | search : terms">
<h2>{{c.name}}</h2>
</ion-item>
</button>
</ion-list>
</ion-content>
popup.ts
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ViewController, Events} from 'ionic-angular';
import { RestProvider } from './../../providers/rest/rest';
import { HomePage } from './../../pages/home/home';
/**
* Generated class for the PopupPage page.
*
* See https://ionicframework.com/docs/components/#navigation for more info on
* Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-popup',
templateUrl: 'popup.html',
})
export class PopupPage {
rangeSettings = 20;
weapons: any;
errorMessage: string;
constructor(public navCtrl: NavController, public navParams: NavParams, public viewCtrl: ViewController, public rest: RestProvider) {
alert('inside the popup');
}
close() {
this.viewCtrl.dismiss();
}
getweapons() {
this.rest.getweapons()
.subscribe(
weapons => this.weapons = weapons,
error => this.errorMessage = <any>error);
}
ionViewDidLoad() {
this.getweapons();
}
}
popup.html
<ion-header>
<ion-navbar>
<ion-title>popup</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let c of weapons?.weapon_category?.weapons">
<h2>{{c.damage.base}}</h2>
<h2>{{c.damage.chest0}}</h2>
<h2>{{c.damage.chest1}}</h2>
<h2>{{c.damage.chest2}}</h2>
<h2>{{c.damage.chest3}}</h2>
<h2>{{c.damage.head1}}</h2>
<h2>{{c.damage.head2}}</h2>
<h2>{{c.damage.head3}}</h2>
</ion-item>
<ion-item>
<ion-range min="0" max="80" [(ngModel)]="rangeSettings" color="danger" pin="true" snaps="true" disabled=true></ion-range>
</ion-item>
</ion-list>
</ion-content>

Popover doesn't need to hit the REST call again. You can pass the chosen weapon to the popover as a parameter.
Change your function to accept a weapon (make sure you change the code in the HTML too)
presentPopover(myEvent, weapon)
And send it to the popover controller this way:
this.popoverCtrl.create(PopupPage, weapon);
Now in your popup.ts, decleare a weapon object in your class,
weapon : any;
and grab the weapon from the navParams in your constructor
this.weapon = this.navParams.data;
Change your <ion-item> in popup.html to display the selected one.
<ion-item>
{{weapon.damage.base}}
...
</ion-item>

Related

Runtime Error = object is not a function

I'm developing my first aplication with Ionic, and would like to display the firebase data at home.html, but when I start the serve show me this message in browser:
object(...) is not a function
I create this code at home.ts:
import { Component } from '#angular/core';
import { NavController, IonicPage } from 'ionic-angular';
import { ShoppingListService } from '../../services/shopping-list/shopping-list.service';
import { AjaxObservable } from 'rxjs/observable/dom/AjaxObservable';
import { Observable } from 'rxjs/Observable';
import { Item } from '../../models/item/item.model';
#IonicPage()
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
shoppingList$ : Observable <Item[]>;
constructor(public navCtrl: NavController, private shopping:ShoppingListService) {
this.shoppingList$ = this.shopping
.getShoppingList() //pega a lista do banco de dados
.snapshotChanges() //chave e valor das infos do bd
.map(changes => {
return changes.map(c => ({
key: c.payload.key,
...c.payload.val(),
}));
});
}
}
After this, I create the home.html:
<ion-content padding>
<ion-list>
<ion-list-header>
Items
</ion-list-header>
<ion-item *ngFor="let item of shoppingList$ | async">
{{item.nomecontratante}}
</ion-item>
</ion-list>
</ion-content>
Thanks for help me!

Not able to display data from post in ionic

I'm trying to get data that I get from a post call and display in my html page in ionic.
My Ts code is
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '#angular/common/http';
#IonicPage()
#Component({
selector: 'page-fashion',
templateUrl: 'fashion.html',
})
export class FashionPage {
users: any;
body: Object = {
"id": 1014,
"filter": null,
"lat": 13.05831,
"lng": 80.21195,
"mapRadius": 5,
"pageSize": 50,
"pageStart": 1,
"priceRangeFrom": 0,
"priceRangeTo": 100000
};
constructor(public navCtrl: NavController, public navParams: NavParams, public httpClient: HttpClient) {
this.users = this.httpClient.post('myapi',this.body);
this.users.subscribe(data => {
this.users = data;
console.log('my data: ', data);
console.log("the users data ------------>",this.users);
})
}
}
And my html page is
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Fashion</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list inset>
<ion-item *ngFor="let user of (users | async) ">
<h2>{{user.Name}}</h2>
<p>Price : {{user.Price}}</p>
</ion-item>
</ion-list>
</ion-content>
The error is InvalidPipeArgument: '[object Object]
but i am also getting the data before the error message comes, so when i click on close on the above image i am getting my data, but i need to get it as soon as get into the page
EDIT1: I am Getting the data only when i switch to a different tab and come back to this
EDIT2: Guys a I forgot to mention what my api returns, It gives me [34]
i.e.
[{
....
},
..
].
There is an error in your aync pipe declaration it should be like below . Also you are using the same users property to create the Observable and store the data. Create a new property to store the data.
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Fashion</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list inset>
<ion-item *ngFor="let user of userData | async ">
<h2>{{user.Name}}</h2>
<p>Price : {{user.Price}}</p>
</ion-item>
</ion-list>
</ion-content>
edit : create a new property like userData:any[] = [] in your component as use it like below -
export class FashionPage {
users: any;
userData:any[] = []
body: Object = {
"id": 1014,
"filter": null,
"lat": 13.05831,
"lng": 80.21195,
"mapRadius": 5,
"pageSize": 50,
"pageStart": 1,
"priceRangeFrom": 0,
"priceRangeTo": 100000
};
constructor(public navCtrl: NavController, public navParams: NavParams, public httpClient: HttpClient) {
this.users = this.httpClient.post('myapi',this.body);
this.users.subscribe(data => {
this.userData = data;
console.log('my data: ', data);
console.log("the users data ------------>",this.userData);
})
}
}
Initialize users: any; as users = []; since async requires an
observable or an array
Also change the variable name of subscription,
this.users = this.httpClient.post('myapi',this.body);
to,
this.userResult = this.httpClient.post('myapi',this.body);
change html to <ion-item *ngFor="let user of users | async ">
HTML:
<ion-item *ngFor="let user of users | async ">
<h2>{{user.Name}}</h2>
<p>Price : {{user.Price}}</p>
</ion-item>
So TS:
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '#angular/common/http';
#IonicPage()
#Component({
selector: 'page-fashion',
templateUrl: 'fashion.html',
})
export class FashionPage {
users: any;
....
constructor(public navCtrl: NavController, public navParams: NavParams, public httpClient: HttpClient) {
this.userResult = this.httpClient.post('myapi',this.body);
this.userResult.subscribe(data => {
this.users = data;
console.log('my data: ', data);
console.log("the users data ------------>",this.users);
})
}
}
The api returns me [34], i.e. array of 34 objects in it.
I needed a separate variable to store the data and to call the api.
So the code that works to get me the data is
HTML code
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Fashion</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list inset>
<ion-item *ngFor="let user of userData">
<h2>{{user.Name}}</h2>
<p>Price : {{user.Price}}</p>
</ion-item>
</ion-list>
</ion-content>
TS code
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '#angular/common/http';
#IonicPage()
#Component({
selector: 'page-fashion',
templateUrl: 'fashion.html',
})
export class FashionPage {
users: any;
userData = [];
body: Object = {
"id": 1014,
"filter": null,
"lat": 13.05831,
"lng": 80.21195,
"mapRadius": 5,
"pageSize": 50,
"pageStart": 1,
"priceRangeFrom": 0,
"priceRangeTo": 100000
};
constructor(public navCtrl: NavController, public navParams: NavParams, public httpClient: HttpClient) {
this.users = this.httpClient.post('myapi',this.body);
this.users.subscribe(data => {
this.userData = data;
console.log('my data: ', data);
console.log("the users data ------------>",this.userData);
})
}
}
You guys are always wonderful,this community has never failed me once...Thanks a million to all for your valuable time to get me the answer!!!!!!!!

How to include the user credentials in every sidebar of very pages in ionic

I want to have an sidebar that can display the name of the user who logged in. I have an account page that display all the details of the user. This is the code of the typescript below for the accounts page.
import { Component } from '#angular/core';
import { NavController, AlertController} from 'ionic-angular';
import {Headers} from "#angular/http";
import 'rxjs/add/operator/map';
import {Storage} from "#ionic/storage";
import { Global } from '../../providers/global';
#Component({
selector: 'page-account',
templateUrl: 'account.html',
})
export class AccountPage {
constructor(public navCtrl: NavController,
private storage: Storage,
public alertCtrl: AlertController,
public global: Global
)
{
//
}
public ACCOUNT_URL = this.global.url + "/api/inspectors";
credentials:any;
contentHeader = new Headers({"Content-Type": "application/json"});
error: any;
user: any;
token_type: any;
access_token: any;
refresh_token:any;
ionViewDidLoad() {
console.log('ionViewDidLoad AccountPage');
this.getAccessToken();
this.getAccount();
}
getAccessToken(){
this.storage.get('access_token').then((value) => {
this.access_token=value;
});
}
getAccount(){
this.storage.get('user').then((value) => {
this.user=value;
});
}
}
and this is the code in my html.
<ion-header>
<ion-navbar color="danger">
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>Account</ion-title>
</ion-navbar>
</ion-header>
<ion-content class="page-account">
<ion-card>
<ion-item *ngIf="user">
<ion-card-content text-wrap>
<h2>Name: {{user.name}}</h2>
<p>{{user.cellphone_no}}</p>
<p> Address: {{user.address}} </p>
<p> Email: {{user.email}} </p>
</ion-card-content>
</ion-item>
</ion-card>
</ion-content>
What I want to happen is to delete the account pages and put the details of the user in top of the sidebar. So I have to put it into the app.html or app.ts but how can I define the property in my root component in order to display the details of that user.
Here is the code below in my app.component.ts
import { Component, ViewChild} from '#angular/core';
import { Nav, Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import {Storage} from "#ionic/storage";
import { LoginPage } from '../pages/login/login';
import { AccountPage } from '../pages/account/account';
import { InspectionPage } from '../pages/inspection/inspection';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = LoginPage;
#ViewChild(Nav) nav: Nav;
pages: Array<{title: string, component: any, icon: string, color: string}>;
constructor(platform: Platform,
statusBar: StatusBar,
private storage: Storage,
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();
});
// used for an example of ngFor and navigation
this.pages = [
//{ title: 'Home', component: HomePage, icon: 'home', color: 'primary' },
{ title: 'Home', component: InspectionPage, icon: 'home', color: 'danger' },
{ title: 'Account', component: AccountPage, icon: 'person', color: 'primary' }
];
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
logout() {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.storage.remove('access_token');
this.storage.remove('username');
this.storage.remove('data');
this.storage.remove('user');
this.nav.setRoot(LoginPage);
}
}
and here is the code in my sidemenu or html.
<ion-menu [content]="content" id="myMenu">
<ion-header>
<ion-toolbar color="danger">
<ion-title>Menu</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<button menuClose ion-item *ngFor="let p of pages" (click)="openPage(p)">
<ion-icon [name]="p.icon" [color]="p.color" item-left></ion-icon> {{p.title}}
</button>
<button menuClose ion-item (click)="logout()">
<ion-icon name="log-out" color="default" item-left></ion-icon> Logout
</button>
</ion-list>
</ion-content>
</ion-menu>
<!-- Disable swipe-to-go-back because it's poor UX to combine STGB with side menus -->
<ion-nav [root]="rootPage" #content swipeBackEnabled="false"></ion-nav>
What I want to happen is to put the details of the user in the sidebar like what I did in the account page. Sorry for my long question. I tried searching for it but can't find any answer to it.
Looking for help.
Thanks in advance.
I would recommend that you create a service to handle the state of the user login. That way the state is handled in a central place and it will be much easier to maintain.
One possible approach would be to use a BehaviourSubject inside your service, which you can then subscribe to on every page that you need your user object (like your account page and your app component).
import {Injectable} from '#angular/core'
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
#Injectable()
export class UserService {
// Observable user object (replace any with your user class/interface)
private _userObject = new BehaviorSubject<any>({});
// Expose an observable that can be used by components
userObject$ = this._userObject.asObservable();
// Method to update the user
changeUser(user) {
this._userObject.next(user);
}
}
You can now use the service like that (you have to implement the subscription logic in every component where you want to have access to your user):
import {Component} from '#angular/core';
import {UserService} from './user.service';
#Component({
selector: 'account-page'
})
export class AccountPage {
user: any;
subscription: Subscription;
constructor(private _userService: UserService) {}
ngOnInit() {
this.subscription = this._userService.userObject$
.subscribe(item => this.user = item);
}
ngOnDestroy() {
// prevent memory leak when component is destroyed
this.subscription.unsubscribe();
}
login() {
this._userService.changeUser({
name: 'Name' // Replace with name / user object
});
}
logout() {
this._userService.changeUser({});
}
}
As mentioned above, the big advantage is maintainability. If you ever change your user object, it only requires minimal changes, whereas the solution by #Tomislav Stankovic requires changes in every component where the user is used.
In your login page, when user is successfully logged-in, store data to localStorage
login(username,password){
this._api.userLogin().subscribe(res => {
if(res.status == 'ok'){
localStorage.setItem('user_first_name', res.user_first_name);
localStorage.setItem('user_last_name', res.user_last_name);
}
}
And then in app.component.ts get data from localStorage
this.first_name = localStorage.getItem('user_first_name');
this.last_name = localStorage.getItem('user_last_name');
Display data in app.html
<p>{{first_name}}</p>
<p>{{last_name}}</p>
On log-out clear localStorage
logout(){
localStorage.clear();
}

Filter JSON by specific value ionic 2

im new in IOnic 2 and Angular, i try to filter a Json to show only a especific value; example get only user by gender. this is my code
home.html
<ion-list>
<ion-item *ngFor="let item of items | filter: {item.gender:'female'}" (click)="itemClicked($event,item)">
<ion-avatar item-left>
<img src="{{item.picture.thumbnail}}">
</ion-avatar>
<h2>{{item.name.first | uppercase }}</h2>
<h3>{{item.name.last | uppercase }}</h2>
<p>{{item.gender}}</p>
<button ion-button item-right color="danger" (click)="buttonClick($event)">Button</button>
</ion-item>
</ion-list>
This is my .ts file with the API Service
import { Component } from '#angular/core';
import {Http} from '#angular/http';
import { NavController } from 'ionic-angular';
import 'rxjs/add/operator/toPromise';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public items:any;
constructor(public navCtrl: NavController,public http: Http) {
this.http = http;
this.http.get("http://api.randomuser.me/?results=10")
.subscribe(data =>{
//console.log(data['_body']);
this.items=JSON.parse(data['_body']).results;//Bind data to items object
},error=>{
console.log(error);// Error getting the data
} );
}
buttonClick(event){
console.log("button clicked");
console.log(event);
}
itemClicked(event,itemData){
console.log("item clicked");
console.log(event);
console.log(itemData);
}
}
But my idea does not work
any idea to help me-?? :`/
You can do that in the component code instead of in the view...
import { Component } from '#angular/core';
import {Http} from '#angular/http';
import { NavController } from 'ionic-angular';
import 'rxjs/add/operator/toPromise';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public items: any;
constructor(public navCtrl: NavController, public http: Http) {
// this.http = http; <- You don't need this, this.http is already available because by declaring it in the constructor, now a public property is created in the component
this.http.get("http://api.randomuser.me/?results=10")
.map(data => data.json().results) // Instead of getting the _body manually, you can use the map method from RxJS
.subscribe(data =>{
//console.log(data);
this.items = data.filter(item => item.gender === 'female');
},error=>{
console.log(error);// Error getting the data
});
}
// ...
}
And now in your view
<ion-list>
<ion-item *ngFor="let item of items" (click)="itemClicked($event,item)">
<ion-avatar item-left>
<img src="{{ item.picture.thumbnail }}">
</ion-avatar>
<h2>{{ item.name.first | uppercase }}</h2>
<h3>{{ item.name.last | uppercase }}</h2>
<p>{{ item.gender }}</p>
<button ion-button item-right color="danger" (click)="buttonClick($event)">Button</button>
</ion-item>
</ion-list>

how to use ion-toggle in notification using ionic2

I am doing notifications in ionic 2 i have taken one toggle button and wrote the get and post call for that one.
below is my html code.
<ion-header>
<ion-navbar>
<ion-title>Notifications</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-item no-lines (click)="Update()">
<ion-label> Notification</ion-label>
<ion-toggle checked={{notify}} ></ion-toggle>
</ion-item>
</ion-content>
below is my ts file..
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { Logger } from '../../providers/logger/logger';
import { Rest } from '../../providers/network/rest';
/*
Generated class for the Notifications page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-notifications',
templateUrl: 'notifications.html'
})
export class NotificationsPage {
public noteValue;
public notify : boolean;
NotificationsArray=[];
constructor(public navCtrl: NavController,
public logger: Logger,
public rest: Rest){
}
ionViewDidLoad() {
this.rest.get('/getNotification')
.subscribe((result)=>
{
console.log("checking getNotification"+JSON.stringify(result));
//this.logger.debug(["getNotification"][0]["newsletter"]);
if(result.status == '1'){
if(result.notify == '1'){
this.notify=true;
console.log("success of getNotification");
//this.NotificationsArray=result.data;
}
else{
this.notify=false;
console.log("error of getNotification");
}
}
})
}
Update(){
let setNotificationObj = {
newsletter:this.notify
}
this.notify = !this.notify;
console.log("cheking setNotificationObj " + JSON.stringify(setNotificationObj));
this.rest.post('/setNotification',setNotificationObj)
.subscribe((result)=>
{
console.log("checking data of success " +JSON.stringify(result));
if(result.status == '1'){
}
else{
console.log("error");
}
});
}
}
my get call is working but when i am off&on the toggle button its getting json at position 0 error. please check my post call..