This question is locked. New answers and comments are not allowed.
In my NativeScript angular project I am using a radlistview to display a list of messages from a firebase backend. In Android the list item is displaying correctly however in IOS I am getting the following error and the application is terminated:
CONSOLE WARN file:///app/tns_modules/tns-core-modules/application/application.js:212:26: Fatal JavaScript exception - application has been terminated.file:///app/tns_modules/nativescript-telerik-ui/listview/listview.js:1311:20: JS ERROR TypeError: undefined is not an object (evaluating 'type.toLowerCase')
I am using the latest version of the nativescript-telerik-ui 3.1.0 and tns 3.2.
My code for the template, component and service is as follows, Please let me know what I need to change.
Component.html
<GridLayout rows="*" class="m-x-10"> <RadListView [items]="this.messagesForView" [itemTemplateSelector]="templateSelector"> <ng-template tkTemplateKey="testPrint" let-item="item"> <!--For testPrint messages--> <GridLayout rows="auto auto" columns="auto *"> <Label row="0" col="0" text="" class="fa p-t-4 m-y-5"></Label> <Label row="0" col="1" [text]="'Your item ' + item.testName + 'is ready for download at ' + item.testLink"></Label> <Label row="1" col="1" text="11:50" horizontalAlignment="right"></Label> </GridLayout> </ng-template> <ng-template tkTemplateKey="otherMessage" let-item="item"> <!--For Other Messages--> <GridLayout rows="auto auto" columns="auto *"> <Label row="0" col="0" text="" class="fa p-t-4 m-y-5"></Label> <Label row="0" col="1" [text]="item.body"></Label> <Label row="1" col="1" text="13:10" horizontalAlignment="right"></Label> </GridLayout> </ng-template> </RadListView> </GridLayout>
Component.ts
import { AfterContentInit, Component, OnInit, OnDestroy } from "@angular/core";import { NavigationExtras, Router } from "@angular/router";import { RouterExtensions } from "nativescript-angular";import { android } from "application"; // THis is to import application for handleing back button.import { Subscription } from "rxjs/Rx";import { Page } from "ui/page";import { Location } from "@angular/common";//import ui elementsimport scrollViewModule = require("ui/scroll-view");// import htmlViewModule = require("ui/html-view");import { ListViewEventData, RadListView } from "nativescript-telerik-ui/listview"; //This import is for rad list and event data on radList.import { topmost } from "ui/frame"; //To catch the rad list component as view.import { View } from "ui/core/view"; //To use a component as a View.import { isTablet } from "../shared/device-constant/device.constant";import { UserStatusService } from "../services/userStatus.service";import { FirebaseMessagingService } from "../services/firebase-messaging.service";import { AndroidBAckButtonHandlerService } from "../services/androidBackButtonHandler.service";import { ObservableArray } from "data/observable-array";@Component({ moduleId: module.id, selector: "messaging", styleUrls: [(isTablet ? '../tablet.css' : '../phone.css')], templateUrl: "./messaging.component.html",})export class MessagingComponent implements OnInit, OnDestroy { uid: string; private backButtonHandler: Subscription; public isTablet: boolean; public messagesForView: ObservableArray<any>; private _templateSelector: (item: any, index: number, items: any) => string; public messagesSubscriber: Subscription; constructor(private router: Router, private routerExtensions: RouterExtensions, private location: Location, private userStatusService: UserStatusService, private firebaseMessagingService: FirebaseMessagingService, private page: Page, private androidBAckButtonHandlerService: AndroidBAckButtonHandlerService) { } public ngOnInit() { this.messagesForView = new ObservableArray(); this._templateSelector = this.templateSelectorFunction; this.page.actionBarHidden = true; this.messagesSubscriber = this.firebaseMessagingService.messagesReceived.subscribe((currentMessages) => { this.messagesForView.push.apply(this.messagesForView, currentMessages); }); this.firebaseMessagingService.getMessageFromFirebase(); if (this.firebaseMessagingService.getMessages() !== undefined) { this.messagesForView = JSON.parse(this.firebaseMessagingService.getMessages()); } else { const welcomeMessage = { type: "otherMessage", testName: "Trial Test", testLink: "Trial Link", title: "Welcome", body: "Hello", }; this.messagesForView.push(welcomeMessage); } //Subscribing android back button event emitter. this.backButtonHandler = this.androidBAckButtonHandlerService.detailTestBackHandler.subscribe((status) => { console.log("Back button pressed on detail test component and the status is: " + JSON.stringify(status)); }); } get dataItems(): ObservableArray<any> { return this.messagesForView; } get templateSelector(): (item: any, index: number, items: any) => string { return this._templateSelector; } set templateSelector(value: (item: any, index: number, items: any) => string) { this._templateSelector = value; } public templateSelectorFunction = (item: any, index: number, items: any) => { return item.messageType; } public ngOnDestroy() { if (android) { this.backButtonHandler.unsubscribe(); console.log("Back button handler is unsubscribed !!"); } }}
Service.ts
import { Injectable, EventEmitter, NgZone } from "@angular/core";import firebase = require("nativescript-plugin-firebase");import { Observable } from 'rxjs/Observable';import { BehaviorSubject } from 'rxjs/BehaviorSubject';import 'rxjs/add/operator/share';import { setString, getString, remove } from "application-settings";import { ObservableArray } from "tns-core-modules/data/observable-array";@Injectable()export class FirebaseMessagingService { public messagesReceived: BehaviorSubject<any> = new BehaviorSubject({}); constructor( private ngZone: NgZone, ) { } // Get the User's messages public getMessageFromFirebase(): void { console.log("I have come to get my messages"); firebase.addOnMessageReceivedCallback( (message) => { if (message) { //create message object let currentMessages = new ObservableArray(); const newMessage = this.createMessageObject(message); if (this.getMessages() !== undefined) { currentMessages.push.apply(currentMessages, JSON.parse(this.getMessages())); } console.log("Current Messages is " + currentMessages); currentMessages.push(newMessage); console.log("After pushing Current Messages is " + currentMessages); this.setMessages(JSON.stringify(currentMessages)); this.messagesReceived.next(currentMessages); } }, ); } createMessageObject(message) { console.log("Message Data type is" + message.type); console.log("Type of the message type is" + typeof (message.type)); if (message.type === "testPrint") { const messageObject = { messageTestName: message.title, messageType: message.type, messageBody: message.body, messageTestLink: message.testLink, }; return messageObject; } else { const messageObject = { messageTitle: message.title, messageType: message.type, messageBody: message.body, }; return messageObject; } } setMessages(storedMessages: string) { setString('storedMessages', (storedMessages)); } getMessages() { return getString('storedMessages'); } removeMessages() { remove('storedMessages'); }}
Thank you.