ListView not working


#1

Hi Everyone,

i just went through tutorial to start building an android app, and i’m stuck in ListView.

i have array of Object inside ListComponent’s ngOnInit() method.

this method doesn’t rendered to template’s ListView.

by the way if i rendered only one value like String for example with a simple lable it will work properly.

list.component.ts

import { Component, ElementRef, OnInit, ViewChild } from "@angular/core";

@Component({
  selector: "list",
  templateUrl: "pages/list/list.html",
  styleUrls: ["pages/list/list-common.css", "pages/list/list.css"]
})
export class ListComponent implements OnInit {
  groceryList: Array<Object> = [];

  ngOnInit() {
    this.groceryList.push({ name: "Apples" });
    this.groceryList.push({ name: "Bananas" });
    this.groceryList.push({ name: "Oranges" });
	console.dir(this.groceryList)
  }
}

list.html

<GridLayout>
  <ListView [items]="groceryList" >
    <ng-template let-item="item">
      <Label [text]="item.name"></Label>
    </ng-template>
  </ListView>
</GridLayout>

app.routing.ts

import { LoginComponent } from "./pages/login/login.component";
import { ListComponent } from "./pages/list/list.component";

export const routes = [
  { path: "", component: LoginComponent },
  { path: "list", component: ListComponent }
];

export const navigatableComponents = [
  LoginComponent,
  ListComponent
];

What would be the problem?


#2

Hey @SULTAN,
The problem you are facing here is that your ListView is created first( groceryList is empty or undefined),
then secondly you are adding elements to your array which is not an Observable array( You are not handling the event of values added to your array).

Things you should learn first.

  1. Lifecycle of {N} app.
  2. Binding Data in Angular + {N} apps.

Short Solution to your problem:

Add this code to list.component.ts :

public constructor() {
    this.groceryList =[
                        { name: "Apples" },
                        { name: "Bananas" },
                        { name: "Oranges" }];
                  }

#3

Could someone help me please :confused:


#4

Does @deepak4u2006’s solution work for you?


#5

Thanks for replying

i updated groceryList value but still not working. i’m going to more files it might be helpful.

package.json

{
  "description": "NativeScript Application",
  "license": "SEE LICENSE IN <your-license-filename>",
  "readme": "NativeScript Application",
  "repository": "<fill-your-repository-here>",
  "nativescript": {
    "id": "org.nativescript.Groceries",
    "tns-android": {
      "version": "3.0.0"
    }
  },
  "dependencies": {
    "@angular/animations": "~4.0.0",
    "@angular/common": "~4.0.0",
    "@angular/compiler": "~4.0.0",
    "@angular/core": "~4.0.0",
    "@angular/forms": "~4.0.0",
    "@angular/http": "~4.0.0",
    "@angular/platform-browser": "~4.0.0",
    "@angular/platform-browser-dynamic": "~4.0.0",
    "@angular/router": "~4.0.0",
    "nativescript-angular": "~3.0.0",
    "nativescript-theme-core": "~1.0.4",
    "reflect-metadata": "~0.1.8",
    "rxjs": "~5.2.0",
    "tns-core-modules": "~3.0.0",
    "zone.js": "0.8.2"
  },
  "devDependencies": {
    "babel-traverse": "6.4.5",
    "babel-types": "6.4.5",
    "babylon": "6.4.5",
    "lazy": "1.0.11",
    "nativescript-dev-android-snapshot": "^0.*.*",
    "nativescript-dev-typescript": "^0.4.0",
    "typescript": "~2.2.1"
  }
}

tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "noEmitHelpers": true,
        "noEmitOnError": true,
        "lib": [
            "es6",
            "dom",
            "es2015.iterable"
        ],
        "baseUrl": ".",
        "paths": {
            "*": [
                "./node_modules/tns-core-modules/*",
                "./node_modules/*"
            ]
        }
    },
    "exclude": [
        "node_modules",
        "platforms",
        "**/*.aot.ts"
    ]
}

app.module.ts

import { NgModule } from "@angular/core";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { NativeScriptHttpModule } from "nativescript-angular/http";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptRouterModule } from "nativescript-angular/router";

import { AppComponent } from "./app.component";
import { routes, navigatableComponents } from "./app.routing";

@NgModule({
  imports: [
    NativeScriptModule,
    NativeScriptFormsModule,
    NativeScriptHttpModule,
    NativeScriptRouterModule,
    NativeScriptRouterModule.forRoot(routes)
  ],
  declarations: [
    AppComponent,
    ...navigatableComponents
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

app.component.ts

import { Component } from "@angular/core";

@Component({
  selector: "main",
  template: "<page-router-outlet></page-router-outlet>"
})
export class AppComponent {}

user.service.ts

import { Injectable } from "@angular/core";
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";

import { User } from "./user";
import { Config } from "../config";

@Injectable()
export class UserService {
  constructor(private http: Http) {}

  register(user: User) {
    let headers = new Headers();
    headers.append("Content-Type", "application/json");

    return this.http.post(
      Config.apiUrl + "Users",
      JSON.stringify({
        Username: user.email,
        Email: user.email,
        Password: user.password
      }),
      { headers: headers }
    )
    .catch(this.handleErrors);
  }
	
	login(user: User) {
  let headers = new Headers();
  headers.append("Content-Type", "application/json");
	console.log(Config.apiUrl)
  return this.http.post(
    Config.apiUrl + "oauth/token",
    JSON.stringify({
      username: user.email,
      password: user.password,
      grant_type: "password"
    }),
    { headers: headers }
  )
  .map(response => response.json())
  .do(data => {
    Config.token = data.Result.access_token;
  })
  .catch(this.handleErrors);
  
  
}
  handleErrors(error: Response) {
    console.log(JSON.stringify(error.json()));
    return Observable.throw(error);
  }
  
}

login.component.ts

import { Color } from "color";
import { View } from "ui/core/view";
import { Component , OnInit , ElementRef , ViewChild } from "@angular/core";
import { User } from "../../shared/user/user";
import { UserService } from "../../shared/user/user.service";
import { Router } from "@angular/router";
import { Page } from "ui/page";

@Component({
  selector: "my-app",
  providers: [UserService],
  templateUrl: "pages/login/login.html",
  styleUrls: ["pages/login/login-common.css", "pages/login/login.css"],
})
export class LoginComponent implements OnInit{
  user: User;
  isLoggingIn = true;
  
  @ViewChild("container") container: ElementRef; //This is link container variable from login.html to ElementRef's container variable
  constructor(private router: Router, private userService: UserService, private page: Page) {
  this.user = new User();
  
}
  submit() {
  if (this.isLoggingIn) {
    this.login();
  } else {
    this.signUp();
  }
}
login() {
  /* this.userService.login(this.user)
    .subscribe(
      () => this.router.navigate(["/list"]),
      (error) => alert("Unfortunately we could not find your account.")
    ); */
	this.router.navigate(["/list"])
}
signUp() {
	
  this.userService.register(this.user)
    .subscribe(
      () => {
        alert("Your account was successfully created.");
        this.toggleDisplay();
      },
      () => alert("Unfortunately we were unable to create your account.")
    );
}
	toggleDisplay() {
	  this.isLoggingIn = !this.isLoggingIn;
	  let container = <View>this.container.nativeElement;
	  container.animate({ backgroundColor: this.isLoggingIn ? new Color("white") : new Color("#ffbf00"), duration: 200});
	}  
	  ngOnInit() {
  this.page.actionBarHidden = true;
  this.page.backgroundImage = "res://bg_login";
}
}

and sorry for this long post.


#6

i just created a new project and went through the tutorial again and it’s worked perfectly. :slight_smile:
then i coped the content of new files to previous one but unfortunately, the ListView not coming on list.component’s template. :confused:


#7

Is the problematic device a Samsung by any chance?