Angular 2 Reading List with ngFor on View? - angularjs

I'm trying List reading from WebApi with ngFor but it doesn't work for me.
export class MembershipPage {
memberships: any = [];
constructor(public navCtrl: NavController, public authservice: AuthService) {
}
ionViewDidEnter() {
this.authservice.getmembers().then(
data => {
this.memberships.push(data);
}
);
}
and i'am calling from view like this`
<ion-content>
<ion-list>
<ion-item *ngFor="let member of memberships">{{member.Name}}
</ion-item>
</ion-list>
Getting my data [Object object] on my ion-item. What's the problem? I don't understand.

Try this:
ionViewDidEnter() {
this.authservice.getmembers().then( data => {
this.memberships = data;
} );
}

Related

Error trying to diff '[object Object]'. Only arrays and iterables are allowed but i dont see anything wrong with my code

I have been having this problem for the past week, I have searched everywhere but wasn't able to find a problem.
My service
private texst!: Posts[];
public getPosts(): Observable<Posts[]>
{
return this.http.get<Posts[]>("http://localhost/projects/php_rest_api/api/post/read.php").pipe(map((data) => {
return this.texst = data;
}));
}
My Component, here i add the service and run the function to get the data from my database
public test: Posts[] = [];]
constructor(public postService: PostsService,
private http: HttpClient) {}
ngOnInit(): void {
this.getPosts();
}
public getPosts()
{
this.postService.getPosts().subscribe((response) => {
this.test = response;
console.log(this.test);
})
}
My html
<div>
<button (click)="getPosts()"></button>
<div *ngFor="let test of test">
{{test.title}}
</div>
</div>
Change this, rename your var test to testItem because it's already used:
<div>
<button (click)="getPosts()"></button>
<div *ngFor="let testItem of test">
{{testItem.title}}
</div>
</div>
Managed to fix it
changed the response to object.values in my getPosts() function
public getPosts()
{
this.postService.getPosts().subscribe((response) => {
this.test = Object.values(response);
console.log(this.test);
})
}
It means you're trying to iterate over object, but you think it's an array.
If that image is a log of the response, you better do:
public getPosts()
{
this.postService.getPosts().subscribe((response) => {
this.test = response.data; // <.. this changes!
})
}
and in template:
<div *ngFor="let testItem of test">
{{testItem.title}}
</div>

Edit Items in a List Using Modal in Ionic 3

I have created an Array and I'm adding items to the array using Modal.
Now i need to edit the item by selecting it from the list.
please help me with the Code.
How to fetch the item to modal and bring back the edited item in the same place in the list
HOME.HTML
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item *ngFor="let grocery of itemsArray">{{grocery}}</ion-item>
</ion-list>
<button ion-button round (click)="addItem()">Add Item</button>
</ion-content>
HOME.TS
export class HomePage {
public itemsArray = [];
newItem: any;
constructor(public navCtrl: NavController, public modalCtrl: ModalController, public navParams: NavParams) {
}
ionViewDidLoad() {
this.newItem = this.navParams.get('data');
this.itemsArray = [
];
}
public addItem() {
let modalPage = this.modalCtrl.create(ModalPage);
modalPage.onDidDismiss(data => {
this.itemsArray.push(data.name
);
});
modalPage.present();
}
}
MODAL.HTML
<ion-header>
<ion-navbar>
<ion-title>Add Item</ion-title>
<ion-buttons end>
<button ion-button (click)="closeModal()">Close</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list>
<ion-item>
<ion-label>Item</ion-label>
<ion-input type="text" [(ngModel)]="newItem"></ion-input>
</ion-item>
<button ion-button color="secondary" (click)="add()">Add Item</button>
</ion-list>
</ion-content>
MODAL.TS
export class ModalPage {
name:any;
newItem: any;
constructor(public navCtrl: NavController, public viewCtrl: ViewController, public navParams: NavParams) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad ModalPage');
}
public closeModal() {
this.viewCtrl.dismiss();
}
//add() {
// let data = {"name": this.newItem};
// this.viewCtrl.dismiss(data.name)
// }
add() {
let data = {"name": this.newItem};
this.viewCtrl.dismiss(data)
}
}
The code untill now works fine.
I would recommend using alert controller to simplify your code in your use case. If you would need a modal - you can elaborate the code later.
Try this approach:
<ion-header>
<ion-navbar>
<ion-title>
Ionic Blank
</ion-title>
</ion-navbar>
</ion-header>
<ion-content>
<ion-list *ngFor="let grocery of itemsArray; let i = index">
<ion-item (click)="changeItemName(grocery, i)">{{grocery}}</ion-item>
</ion-list>
<button ion-button round (click)="addItem()">Add Item</button>
</ion-content>
Place iterator on the list and capture "index" per item, so that you could pass that value if particular item from the list is clicked together with actual grocery item name.
In your home.ts:
import { Component } from '#angular/core';
import { NavController, NavParams, AlertController, ViewController } from 'ionic-angular';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
public itemsArray = ["milk", "butter", "bread"];
newItem: any;
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public navParams: NavParams) {
}
public changeItemName(currentName, index) {
let alert = this.alertCtrl.create({
title: 'Change grocery item name:',
message: 'current: "' + currentName + '"',
inputs: [
{
placeholder: 'type in a new name'
}
],
buttons: [
{
text: 'Cancel',
role: 'cancel',
},
{
text: 'Confirm',
handler: data => {
if (data[0].length === 0) {
this.itemsArray[index] = currentName;
} else {
this.itemsArray[index] = data[0];
}
}
}
]
});
alert.present();
};
public addItem() {
let index = this.itemsArray.length;
this.changeItemName("New item", index);
}
}
You can use alert controller to show a small pop-up with input field. In the code you will see that we pass parameters to it and we modify list item name OR we add item to the list if change name method was called by addItem method.
Let me know if this is helpful for you.
Here is a working snippet: https://stackblitz.com/edit/ionic-urbtag

Angular 4 Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

Here is the code below:
component.ts
by selecting match geting id in routing, then taking this id from URL
export class MatchComponent implements OnInit {
_postArrayMatch: match[];
constructor(public router:Router, private matchService: MatchService,
private route: ActivatedRoute) {}
ngOnInit(){
this.getMatchId();
}
getMatchId() :void {
this.route.params.forEach((params: Params)=> {
let id = +params['id'];
this.matchService.getMatch(id).subscribe(
resultArray => this._postArrayMatch = resultArray,
error => console.log("Error ::" + error))
})
}
component.html
just basic interpolation by doing ngFor loop
<div *ngFor="let post of _postArrayMatch">
<p>{{post.team1.name}}</p>
</div>
service.ts
passing the dynamic id
getMatch(id:number): Observable<match[]>{
return this.http.get<match[]>(`http://localhost:3000/match/${id}`)
}
interface
export interface match{
team1:{
name:string,
id:number
}
team2:{
name:string,
id:number
}
}
Try something like this where you create the object in your response
component.ts
export class MatchComponent implements OnInit {
_postArrayMatch: match[];
newArr: Array<Object> = [];
constructor(public router:Router, private matchService: MatchService,
private route: ActivatedRoute) {}
ngOnInit(){
this.getMatchId();
}
getMatchId() :void {
this.route.params.forEach((params: Params)=> {
let id = +params['id'];
this.matchService.getMatch(id).subscribe(
resultArray => {
this._postArrayMatch = resultArray;
const keys = Object.keys(this._postArrayMatch) // new stuff starts here
for(let i = 0; i < keys.length; i++) {
newArr.push(this._postArrayMatch[keys[i]]);
newArr[i]['team'] = keys[i];
}
},
error => console.log("Error ::" + error))
})
}
And then you can access ALL of your sub objects in your html
Component.html
<div *ngFor="let post of newArr">
<p> {{post.team}}: {{post.name}}</p>
</div>
Currently, with what you have you are hard coding for team 1, and if you want to do that then you shouldn't be using the *ngFor
Thats seems the easiest way i could find on how to get the data from objects.
<div *ngFor="let post of objectKeys(_postArrayMatch.team1)">
<div> Team1: {{ _postArrayMatch.team1[post]}}</div>
</div>
component.ts
objectKeys = Object.keys;

Ion-list not refreshing afer model change

I am having a problem with the ion-list, I can list all the items when the app loads for the first time, but when I make any changes to it, adding or removing data, the list isn't updating for the user.
I am using Pouch db to add and remove data for persistence in the app, all the functions are working correctly, it can be confirmed through console.log in the contents or using the fauxton PouchDb extension for chrome.
Resuming, the data is changing, but the view is not reflecting it.
the view code is this notas.html
<ion-content>
<ion-list>
<ion-item-sliding *ngFor="let n of notas">
<ion-item>
<h2>{{n.descricao}}</h2>
<p>URL: {{n.endereco}}</p>
<p>Data de expiração: {{n.vencimento}}</p>
</ion-item>
<ion-item-options side="right">
<button ion-button (click)="editar(n)">
<ion-icon name="paper"></ion-icon>
Editar
</button>
<button ion-button color="danger" (click)="excluir(n)">
<ion-icon name="trash"></ion-icon>
Excluir
</button>
</ion-item-options>
</ion-item-sliding>
</ion-list>
</ion-content>
And the controler code is this notas.ts
...
#Component({
selector: 'page-notas',
templateUrl: 'notas.html'
})
export class NotasPage {
notas: any;
constructor(public navCtrl: NavController, public alertCtrl: AlertController, public pouchDBService: PouchdbProvider) {
//PARA USO DO EXTENSION DO CHROME *POUCHDB Fauxton
(<any>window).PouchDB = PouchDB;
this.notas = [];
}
ionViewDidLoad(){
this.refresh();
}
refresh(){
//console.log(this.notas);
this.notas = [];
this.pouchDBService.getData().then((data) => {
this.notas = data;
console.log(this.notas);
});
// console.log(this.notas);
}
excluir(nota){
let prompt = this.alertCtrl.create({
title: 'Excluir',
message: 'Deseja realmente excluir o registro?',
buttons: [
{
text: 'Cancelar'
},
{
text: 'Excluir',
handler: data => {
this.pouchDBService.delete(nota);
this.notas.pop(nota);
this.refresh();
}
}
]
});
prompt.present();
}
}
...
Not 100% sure on this but usually if the view is not updating, it has to do with the code not running on zone, so:
import { NgZone } from '#angular/core';
...
zone: any = new NgZone({ enableLongStackTrace: false });
And then change your refresh method to:
refresh(){
//console.log(this.notas);
this.notas = [];
this.pouchDBService.getData().then((data) => {
this.zone.run(() => {
this.notas = data;
console.log(this.notas);
});
});
// console.log(this.notas);
}
I believe that should work.

AngularJS Cannot find a differ supporting object '[object Object]' of type 'object' and Parse Query

So when I try to take my data from my parse query and put it in my array I end up with this error Cannot find a differ supporting object '[object Object]' of type 'object'. My Code for the Html and ts file are below. And my model file is also below. Is there a better way to display this data in the list?
Html:
<ion-header>
<ion-navbar>
<ion-title button-right>Trade</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="addTrade()">
<ion-icon name="add"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content>
<ion-searchbar (ionInput)="getItems($event)"></ion-searchbar>
<ion-list [virtualScroll]="items">
<ion-item *virtualItem="let item">
{{ item.offering }} {{item.needs}}
</ion-item>
</ion-list>
</ion-content>
and my ts file
import { Component } from '#angular/core';
import { NavController, NavParams, AlertController } from 'ionic-angular';
import { Items} from "../../trade-model";
var Parse = require('parse');
/*
Generated class for the Trade page.
See http://ionicframework.com/docs/v2/components/#navigation for more info on
Ionic pages and navigation.
*/
#Component({
selector: 'page-trade',
templateUrl: 'trade.html'
})
export class TradePage {
searchQuery: string = ''
items: Items ={
offering: [],
needs: []
}
constructor(public navCtrl: NavController, public navParams: NavParams, public alertCtrl: AlertController) {
Parse.initialize('blankedout','unused', "blankedout");
Parse.serverURL = 'blankedout';
}
ionViewWillEnter(){
this.initializeItems()
}
ionViewWillLeave(){
}
initializeItems() {
var this_ref = this
var Trade = Parse.Object.extend("Trade")
var query = new Parse.Query(Trade);
query.find({
success: function(trades) {
for (var i = 0; i < trades.length; i++) {
this_ref.items.offering = trades[i].get("offer")
this_ref.items.needs = trades[i].get("wants")
}
}
});
}
}
This is the template/interface
export interface Items{
offering: string[];
needs: string[];
}
items is an object. Ionic virtualScroll requires an array to be passed in.
Do you mean to do:
<ion-list [virtualScroll]="items.offering">
<ion-item *virtualItem="let item">
{{ item}}
</ion-item>
</ion-list>

Resources