ionic 2 local storage get and display the data - arrays

hi i cant access my data in localstorage , it always gives me error . i need help in displaying my datas in my home . thank you for your help :)
Error:
Typescript Error
Argument of type 'Promise' is not assignable to parameter of type 'string'.
this.user = JSON.parse(this.storage.get(this.key));
prompt.present();
Typescript
import { Component } from '#angular/core';
import { IonicPage, NavController, NavParams, ViewController, AlertController } from 'ionic-angular';
import {Storage} from '#ionic/storage';
/**
* Generated class for the CrudPage page.
*
* See http://ionicframework.com/docs/components/#navigation for more info
* on Ionic pages and navigation.
*/
#IonicPage()
#Component({
selector: 'page-crud',
templateUrl: 'crud.html',
})
export class CrudPage {
user: any = [] ;
key: any;
constructor(public navCtrl: NavController,
public navParams: NavParams,
public viewCtrl: ViewController,
public alertCtrl: AlertController,
public storage: Storage) {
this.storage.forEach( (value) => {
this.user.push(value);
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad CrudPage');
}
add() {
let prompt = this.alertCtrl.create({
title: 'Add User',
message: "Enter information of the user",
inputs: [
{
name: 'name',
placeholder: 'name'
},
{
name: 'password',
placeholder: 'password'
},
],
buttons: [
{
text: 'Cancel',
handler: data => {
console.log('Cancel clicked!');
}
},
{
text: 'Save',
handler: data => {
let key = data.name + data.password;
this.storage.set(key, JSON.stringify(data));
console.log(data);
}
}
]
});
this.user = JSON.parse(this.storage.get(this.key));
prompt.present();
}
delete(key){
this.storage.remove(key);
}
update(key){
}
}
HTML
<!--
Generated template for the CrudPage page.
See http://ionicframework.com/docs/components/#navigation for more info on
Ionic pages and navigation.
-->
<ion-header>
<ion-navbar>
<ion-title>Crud</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<button ion-button clear icon-start color="dark" (click)="add()">
<ion-icon name="add-circle">Add User</ion-icon>
</button>
<br>
<ion-grid text-center>
<ion-row>
<ion-col width-100>
USERS
</ion-col>
</ion-row>
<ion-row>
<ion-col width-33>
<strong>User Name</strong>
</ion-col>
<ion-col width-33>
<strong>Password</strong>
</ion-col>
<ion-col width-33>
<strong>Action</strong>
</ion-col>
</ion-row>
<ion-row *ngFor="let users of user" text-center>
<ion-col width-33>
<p>{{users.name}}</p>
</ion-col>
<ion-col width-33>
<p>{{users.password}}</p>
</ion-col>
<ion-col width-33>
<button ion-button clear icon-start color="dark" (click)="delete(users.name+users.password)">
<ion-icon name="trash"></ion-icon>
</button>
<button ion-button clear icon-start color="dark" (click)="update(users.name+users.password)">
<ion-icon name="create"></ion-icon>
</button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
Please help :) Thank you very much :)

this.storage.get(this.key) returns a promise, you have to do that:
this.storage.get(this.key).then(value => {
this.user = JSON.parse(value);
});
https://ionicframework.com/docs/storage/

Related

Get value from each *ngFor ionic 4, ionic 5, ionic 6

I have the following code:
<ion-item *ngFor="let box of boxes">
This will show results from array:
On the .ts file i have the following:
isApproved : boolean;
public box: any;
This will generate from boxes array:
box1 -> [id, name, isApproved]
box2 -> [id, name, isApproved]
box3 ->[id, name, isApproved]
I need to get the isApproved value of each box, so when i activate the toggle, isApproved will change in database.
I know one method that doesn't fits my needs, like clicking and getting the id from route but i want to open a new page for that.
Just put and ngModel in the ion-toggle:
html:
<ion-item *ngFor="let box of boxes">
<ion-avatar slot="start"></ion-avatar>
<ion-label>...</ion-label>
<ion-toggle [(ngModel)]="box.isApproved" (ionChange)="approvedToggled($event)"></ion-toggle>
</ion-item>
ts:
approvedToggled(event, box) {
if(event.detail.value) {
// save to box to database
}
/* or:
if(item.isApproved) {
// save to database
}
*/
}
The solution is very simple.
The working code is:
On my HTML:
<div *ngFor="let box of boxes">
<ion-item-sliding id="anyId">
<ion-item>
<ion-avatar slot="start">
<img [offset]="100" [alt]="box.user?.name"
defaultImage="./assets/img/photo.png" [lazyLoad]="box.user?.photo?.url()" />
</ion-avatar>
<ion-label class="ion-text-wrap">
<ion-text color="dark">
<h3 class="bold no-margin">
{{ box.user?.name }}
</h3>
</ion-text>
</ion-label>
</ion-item>
<ion-item-options side="end">
<ion-item-option color="primary" (click)="onDelete(box)">
<ion-icon slot="icon-only" name="trash"></ion-icon>
</ion-item-option>
</ion-item-options>
</ion-item-sliding>
</div>
On my TS i have:
Importing service:
import { Box } from '../../services/box-service';
Before constructor:
public boxes: Box[] = [];
public box: Box;
constructor(private BoxService: Box) {
super(injector);
}
Loading boxes from service:
async loadDataFromService() {
try {
const boxes = await this.boxService.loadBoxes(this.params);
for (let box of boxes) {
this.boxes.push(box);
}
this.onRefreshComplete(boxes);
} catch {
}
}
... this will return an array with arrays. Each array has an object.
Now we just access each box from HTML (click)="onDelete(box)"
async onDelete(box: Box) {
await Swal.fire({
title: 'Are you sure?',
text: 'Blah, blah',
icon: 'warning',
iconColor: '#5038de',
showCancelButton: true,
confirmButtonColor: '#5038de',
cancelButtonColor: '#e0b500',
confirmButtonText: 'Yes',
cancelButtonText: 'No',
heightAuto: false,
showClass: {
popup: 'animated fade-in'
},
hideClass: {
popup: 'animated fade-out'
}
}).then(async (result) => {
if (result.value) {
await this.boxService.deleteBox(box)
this.goTo()
} else {
this.goTo()
}
});
}
}
Resuming, the solution for:
<ion-item *ngFor="let box of boxes">
<ion-avatar slot="start"></ion-avatar>
<ion-label>...</ion-label>
<ion-toggle (ionChange)="myFunction(box)"></ion-toggle>
</ion-item>
was simply (ionChange)="myFunction(box)" or (click)="myFunction(box)"
In my case box will be an entire object, passing the id will be enough to perform any action.

Receive data only from the selected item on another page

I would like that when I click on any item in my list, only show the data of this item on the new page. I can already display the items from page 1 to page 2, but I can not filter. Could someone help me with this?
HTML p1
<ion-segment-button value="Todosgastronomia" class="todos-button"
(click)="selecionaprodutoscategoria(1)">
Todos
</ion-segment-button>
<ion-list *ngSwitchCase="'Todosgastronomia'">
<ion-item no-lines *ngFor="let produto of
produtos(click)="querocomprar()" no-padding>
<ion-thumbnail item-start>
<img src="assets/imgs/mmsszjm.png" class="imgast">
</ion-thumbnail>
<ion-row class="rowclass">
<h3 class="nomproduto"> {{produto.nom_produto}} </h3>
<h3 class="nomsubcategoria">{{produto.nom_subcategoria}} </h3>
<h3 class="descproduto"> {{produto.desc_produto}} </h3>
<h3 class="descdesconto"> {{produto.desc_desconto}}</h3>
<h3 class="valproduto">
<font color="#179c90">R$</font> {{produto.val_produto}}
</h3>
<button ion-button small end class="favproduto">
<ion-icon name="icon-ico_favoritos"></ion-icon>
</button>
<button ion-button class="querotodos">QUERO!
</button>
</ion-row>
</ion-item>
</ion-list>
TS p1
export class HomePage implements OnInit {
videoOptions: VideoOptions;
videoUrl: string;
public regioes: Regiao[];
produtos: Produto[];
querocomprar(produto: number) {
this.navCtrl.push(ConteudoprodutoPage, {
val: this.produtos
})
}
TS p2
export class ConteudoprodutoPage {
produto: Produto;
constructor(private payPal: PayPal, public navCtrl: NavController, public
navParams: NavParams) {
this.produto = navParams.get("valor");
}
On your ion-item just pass the produto as a param
<ion-item no-lines *ngFor="let produto of produtos" (click)="querocomprar(produto)" no-padding>
And on your querocomprar() method on HomePage, get the produto item
querocomprar(produto: any) {
this.navCtrl.push(ConteudoprodutoPage, {'val': produto})
}
Receive the val param data on your ConteudoprodutoPage class
constructor(private payPal: PayPal, public navCtrl: NavController, public navParams: NavParams) {
this.produto = navParams.get("val");
}

How to pass JSON data to a modal in angular 2

I am trying to pop up a modal in angular 2 that will display a list of people. The source of the list is a JSON file. I think the data is not being properly bound to the table in the modal. I am new to angular 2 and am not sure what I am missing.
Service to read JSON file:
returns-json-array-service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs';
#Injectable()
export class ReturnsJsonArrayService {
constructor(private http: Http) {}
getPeople(): Observable<any> {
return this.http.request('./people.json')
.do( res => console.log('HTTP response:', res))
.map(res => res.json().payload)
.do(console.log);
//.map(res => res.json());
/*return this.http.get('./people.json')
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));*/
}
}
SAmple json file: people.json
{
"id": "1",
"name": "David Martinez Ros",
"email": "info#davidmartinezros.com",
"age": "33"
},
{
"id": "2",
"name": "Paco Roberto Corto",
"email": "paco.roberto.corto#gmail.com",
"age": "51"
},
{
"id": "3",
"name": "Silvia Elegante i Latina",
"email": "silvia.elegante.latina#gmail.com",
"age": "30"
}
]
modal-component.ts
import {Component, Input} from '#angular/core';
import {NgbModal, NgbActiveModal} from '#ng-bootstrap/ng-bootstrap';
import { Observable } from 'rxjs';
import { ReturnsJsonArrayService } from './returns-json-array.service';
#Component({
selector: 'ngbd-modal-content',
providers: [ReturnsJsonArrayService],
template: `
<div class="modal-header">
<h4 class="modal-title">Hi there!</h4>
<button type="button" class="close" aria-label="Close" (click)="activeModal.dismiss('Cross click')">
<span aria-hidden="true">×</span>
</button>
<div class="modal-body" *ngFor="let person of peopleData | async" >
<p>One fine body…</p>
<table border=1>
<tr>
<td>
<h3>Id: {{ person.id }}</h3>
</td>
<td>
<h3>name: {{ person.name }}</h3>
</td>
<td>
<h3>email: {{ person.email }}</h3>
</td>
<td>
<h3>age: {{ person.age }}</h3>
</td>
<td>
</tr>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" (click)="activeModal.close('Close click')">Submit</button>
</div>
`
})
export class NgbdModalContent {
#Input() name;
#Input() peopleData: Observable<Array<any>>;
constructor(public activeModal: NgbActiveModal,private peopleService: ReturnsJsonArrayService) {
this.peopleData = this.peopleService.getPeople();
console.log("AppComponent.data:" + this.peopleData);
}
}
#Component({
selector: 'ngbd-modal-component',
templateUrl: './modal-component.html'
})
export class NgbdModalComponent {
constructor(private modalService: NgbModal) {}
open() {
const modalRef = this.modalService.open(NgbdModalContent);
modalRef.componentInstance.name = 'Barb' ;
console.log("Peopledatra on open():" + modalRef.componentInstance.peopleData);
}
}
modal-component.html
<button class="btn btn-primary" (click)="open()">Assign</button>
this.peopleService.getPeople() returns an observable which is cold to activate it and make it hot you must add a subscribe this.peopleService.getPeople().subscribe() the subscribe will take a success method as the first argument like so:
this.peopleService.getPerople().subscribe(
(json) => {
// do something here with the json
}
)
Once the json is returned you can set it to a property within your components scope like so:
this.peopleService.getPerople().subscribe(
(json) => {
this.json = json;
}
)
That property will then be accessible with in the components template.

Page doesn't open on clicking in side menu - ionic 2 app

I am unable to open a page upon clicking it in side menu.
This is my app.component.ts:
this.pages = [
{ title: 'NFC Page', component: NfcPage, note: 'NFC Page' },
{ title: 'Student Details', component: StudentDetails, note: 'Student Details' },
];
This is my app.module.ts:
#NgModule({
declarations: [
StudentDetails,
NfcPage,
],
entryComponents: [
StudentDetails,
NfcPage,
],
This is my nfc.ts page:
import {Component} from '#angular/core';
import {IonicPage, NavController, NavParams} from 'ionic-angular';
import {NFC, Ndef} from '#ionic-native/nfc';
#IonicPage()
#Component({
selector: 'page-nfc',
templateUrl: 'nfc.html',
})
export class NfcPage {
constructor(public navCtrl: NavController,
public navParams: NavParams,
private nfc: NFC,
private ndef: Ndef) {
}
}
This is my nfc.html page:
<ion-header>
<ion-navbar>
<button ion-button menuToggle>
<ion-icon name="menu"></ion-icon>
</button>
<ion-title>NFCPage</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p>NFC Page!</p>
</ion-content>
Student details page opens fine but when I click "Nfc page", nothing happens.
for open the page through the side menu you need to make that page as a rootpage when you click on the side menu option.You may find the below code:-
app.html:
<ion-menu id="myMenu" [content]="mycontent" >
<ion-content>
<ion-list>
<ion-item ion-item small menuClose (click)="nav.setRoot(pages.nfc)">
<ion-icon name="home" item-left menuClose ></ion-icon> NFC
</ion-item >
<ion-item small menuClose (click)="nav.setRoot(pages.std_detils)">
<ion-icon ios="ios-contact" md="ios-contact" item-left ></ion-icon> Student Details
</ion-item>
</ion-list>
</ion-content>
</ion-menu>
<ion-nav #mycontent [root]="rootPage"></ion-nav>
app.component.ts:
this.rootPage = NfcPage;
this.pages = {
"nfc": NfcPage,
"std_detils": StudentDetails,
};
I have managed to find a solution. The problem is in the constructor of nfc.ts module. The two private parameters (private nfc: NFC and private ndef: Ndef) seem to be broken from the plugin that I am using. I removed these two parameters from the constructor and I was able to open the page. Sadly there was no exception thrown in the console or anywhere else. Hope it helps someone.

ng-model binded to the field doesn't work

Using ng-model I wanted to bind fields with the array object this.enhancements[item.id] = { checked: false, qty: 0 }; so whenever the checkbox is checked or input field has some values it will automatically get filled into the array object.
The following is the code I am currently working with. Please advise what am I doing wrong.
home.ts
export class HomePage {
extras: any;
enhancements: any;
constructor(public navCtrl: NavController, public http: Http) {
this.http.get('https://www.example.com/api/enhance/11/?format=json').map(res => res.json()).subscribe(response => {
this.extras = response.Extras;
this.enhancements = {};
this.extras.forEach(item => {
this.enhancements[item.id] = { checked: false, qty: 0 };
})
});
}
onChange(){
console.log( this.enhancements );
}
}
home.html
<ion-content padding>
<ion-grid>
<ion-row *ngFor="let item of extras" id="booking-enhancements-wrap-{{ item.id }}">
<ion-col width-10>
<ion-checkbox (ionChange)="onChange()" ng-model="enhancements[item.id].checked" ng-checked="enhancements[item.id].checked"></ion-checkbox>
</ion-col>
<ion-col width-70>{{ item.name }}</ion-col>
<ion-col width-20><input type="number " id="qty-{{ item.id }} " style="width: 100%; " (input)="onChange()" ng-model="enhancements[item.id].qty" /></ion-col>
</ion-row>=
</ion-grid>
</ion-content>
If you are using ionic2 Then you can't use ng-model
You have to use [(ngModel)]
see https://ionicframework.com/docs/v2/api/components/checkbox/Checkbox/
try this
replace
this.enhancements = {};
to
this.enhancements = [];

Resources