Issue with Observable when reentering page


#1

Hello,

I’m loading data from a json file when entering a page (multidimensional arrays and long objectlists)

   constructor(private router: Router, public appdata: AppDataProvider, public fav: FavoriteService) {
        this.showSpinner = true;
        setTimeout(() => {
            this.loadData()
        }, 500);
    }
    
    loadData(){
        this.appdata.loadData().subscribe(data => {
            this.activeDay = data.scheduleDays[0],
            this.days = data.dayList,
            this.schedule = data.scheduleDays;     
            },  
            error => alert(error)
        );   
        this.showSpinner = false;
    }
 <ActivityIndicator busy="true" visibility="{{showSpinner ? 'visible' : 'collapsed'}}" width="300" height="300" class="activity-indicator"></ActivityIndicator>
        <ListView height="100%" row="1" visibility="{{showSpinner ? 'collapsed' : 'visible'}}" [items]="activeDay.rooms" class="list-group">
            <ng-template nsTemplateKey="header" let-room="item">
                <StackLayout>
                    <Label [text]="room.name" class="list-group-item bg-primary" isUserInteractionEnabled="false" color="white" fontSize="24"></Label>
                    <StackLayout *ngFor="let session of room.sessions"> 
                        <Gridlayout columns="auto, *" rows="auto, *"  class="list-group-item" >
                            <Label row="0" [text]="session.startTimeString + ' - ' + session.endTimeString" textWrap="true" ></Label>  
                            <Label row="1" col="0"  [text]="session.name" (tap)="goToSessionDetail(session)"  class="list-group-item-heading"></Label>
                            <Label row="1" col="1"  text="&#xf005;" horizontalAlignment="right" (tap)="fav.favSession(session)" class="list-group-item-heading"></Label>  
                        </Gridlayout>
                    </StackLayout> 
                </StackLayout>
            </ng-template>
        </ListView>

this works fine when I launch my app and this view gets called as my “homepage”. After navigating to a different page and back again to this page. the view takes a lot of time to load (ERROR TypeError: undefined is not an object (evaluating ‘_co.activeDay.rooms’) sometimes the app also crashes.

Is this a recommended way to initalize a big chunk of data or is there a better way, I already added a timeout to load the data? Do I always have to subscribe to data from the json when entering a page?


#2

Can you try reproducing your issue with a playground example.


#3

It’s a bit difficult to reproduce and see the performance issues.

Basically I am looking for a way to navigate to this page and show a ActivityIndicator while the view is build/all data is initialized.
Without that functionality it takes a few seconds the enter the page and see the content.

btw. do I always have to load the data (subscribe) again from the json if Im renavigating to this page?


#4

If your View / Page is taking so much time to load even when you data is already there locally, then you definitely have a problem with the way you have built the page.

I’m not sure what is AppDataProvider Or whether it fetches from remote server / it’s being alive or gets completed, which is why I had asked you for a Playground setup.


#5

AppdataProvider is getting data from a local json.file

 //this.appdata.loadData() 
  loadData() {
    return this.http.get('/providers/appdata.json').map(data => data.json())
  }
<ActionBar class="action-bar" title="Schedule" flat="true">
    <NavigationButton ios:visibility="collapsed" icon="res://menu" (tap)="onDrawerButtonTap()"></NavigationButton>
    <ActionItem icon="res://navigation/menu" android:visibility="collapsed" (tap)="onDrawerButtonTap()" ios.position="left">
    </ActionItem>
    <ActionItem ios.systemIcon="12" android.systemIcon="ic_menu_search" (tap)="showSeg()" ios.position="right"></ActionItem>
    <ActionItem ios.systemIcon="12" android.systemIcon="ic_menu_search" (tap)="showModal()" ios.position="right" ></ActionItem>
</ActionBar>

<RadSideDrawer #drawer showOverNavigation="true" [drawerTransition]="sideDrawerTransition">
    <StackLayout tkDrawerContent>
        <MyDrawer [selectedPage]="'Schedule'"></MyDrawer>
    </StackLayout>

    <TabView class="page page-content" *ngIf="showContent" style="font-size: 15" tkMainContent>
        <StackLayout *tabItem="{title: 'Listenansicht'}">
            
            <ListPicker class="daypicker" [items]="days" (selectedIndexChange)="selectedIndexChanged($event)" [(ngModel)]="selectedListPickerIndex"></ListPicker>
            <ActivityIndicator *ngIf="showSpinner" [busy]="showSpinner" width="100" height="100" class="activity-indicator"></ActivityIndicator>

            <SessionListView *ngIf="!showSpinner && listSelector == 0" property="time" [data]="activeDay.listtimes"></SessionListView>
            <SessionListView *ngIf="!showSpinner && listSelector == 1" property="room" [data]="activeDay.rooms"></SessionListView>
            <SessionListView *ngIf="!showSpinner && listSelector == 2" property="type" [data]="activeDay.types"></SessionListView>

        </StackLayout>

        <StackLayout *tabItem="{title: 'Programmübersicht'}">
            <StackLayout>
                <ListPicker class="daypicker" [items]="days" (selectedIndexChange)="selectedIndexChanged($event)" [(ngModel)]="selectedListPickerIndex"></ListPicker>
                <SegmentedBar visibility="{{ showSegment ? 'visible' : 'collapsed' }}" width="300" [items]="segmentedBarItems" [(ngModel)]="selectedBarIndex"></SegmentedBar>
                <ScrollView>
                    <StackLayout orientation="horizontal">
                        <AbsoluteLayout class="fixedContainer">
                            <Label [top]="getTimeOffset(i)" *ngFor="let time of activeDay.times; let i = index" [text]="time.name"></Label>
                        </AbsoluteLayout>
                        <ScrollView orientation="horizontal">
                            <GridLayout [columns]="getCol()" [width]="getWidth()" rows="60, auto">
                                <Label *ngFor="let room of activeDay.rooms; let i = index" backgroundColor="white" class="roomSched" [text]="room.name" row="0"
                                    [col]="get(i)"> </Label>
                                <AbsoluteLayout class="container" *ngFor="let room of activeDay.rooms; let i = index" row="1" [col]="get(i)">
                                    <Label height="1" class="hr" [top]="getLineOffset(i)" *ngFor="let time of activeDay.times; let i = index" width="100%" text=""
                                        backgroundColor="gray"></Label>
                                    <Label class="sessionSched" [style.width]="120" *ngFor="let s of room.sessions" [text]="s.name" [top]="(s.startTime - activeDay.startTime)"
                                        [height]="s.duration" backgroundColor="white"></Label>
                                </AbsoluteLayout>
                            </GridLayout>
                        </ScrollView>
                    </StackLayout>
                </ScrollView>
            </StackLayout>
        </StackLayout>
    </TabView>

</RadSideDrawer>

This is my view at the moment. I had to do some workaround to get a nested listview to show multidimenisional arrays in the list view

SESSIONLISTVIEW:

<GridLayout rows="auto, *">
    <ListView row="1"  height="100%" (itemLoading)="onItemLoading($event)" row="1" [items]="data" class="list-group">
            <ng-template nsTemplateKey="header" let-item="item">
                <StackLayout>
                    <Label [text]="item.name" class="list-group-item" isUserInteractionEnabled="false" color="black" fontWeight="bold" fontSize="30"></Label>
                    <StackLayout *ngFor="let session of item.sessions"> 
                        <Gridlayout columns="auto, *" rows="auto, *"  class="list-group-item" >
                            <Label row="0"  class="sessionTime" [text]="session.startTimeString + ' - ' + session.endTimeString" (tap)="goToSessionDetail(session)"></Label>  
                            <Label row="1" col="0" textWrap="true" class="sessionTitle" [text]="session.name" (tap)="goToSessionDetail(session)"></Label>
                            <Label row="0" col="1" text="&#xf02e;" [color]="fav.isSessionFaved(session)" horizontalAlignment="right" verticalAlignment="center" (tap)="fav.favSession(session)" class="fa"></Label>  
                        </Gridlayout>
                       <!-- <StackLayout class="hr-light m-10"></StackLayout>-->
                    </StackLayout> 
                </StackLayout>
            </ng-template>
            
         <!--   <FAB row="1"  (tap)="fabTap()" icon="res://ic_add_white" rippleColor="#f1f1f1" class="fab-button"></FAB> -->
               
    </ListView> 
</GridLayout>