How to limit json data, push/pop next json data, store read/view event and return to previous state

1. I have a local Json data in my asset I can and had not problems calling the data/content.
1 I would like to limit the the content. say I want to display data available on the size of the app screen and then implement infinite scroll so the rest will load upon scrolling. my challenge here is limit json data to some specific number.

2. Currently If the user tap a list from the available content lists, it display content on a detail page. Now, I want to implement a “next” function that will take the user to the next content without going back to the list of data.

3. A read/view confirmation boolean using “temporary storage” that will marked if the user has read the content or not.

4. An optional return function that takes the user back to the exact listing her/she has navigated from without using the infinite scroll this time.

I hope some understand these questions. Dumb maybe but as a beginner ionic i need to asked these. thank you

Ok, on No. 4 I used:

goBackFunction() {
        this.navCtrl.pop();
    }

still trying to figure out 1-3 above.

Okay, I’m going to try and answer a few of these questions for you. Please don’t respond to already solved posts, keep it in this one. Easier to maintain and for other people to see whether a discussion was already solved or not.

Point 1:
Most straight forward solution is to just slice (with the slice pipe) your data in the view according to a variable that you’ve set in your class. Something like this:

<ion-item *ngFor='let item of items | slice:start_at_item:end_at_item'>

In your class simply set start_at_item at your desired start item (let’s say 0) and and your end_at_item at your desired limit (let’s say 4). Now only five items will be shown in your view. On your infinite scroll simply change end_at_item into a higher number every time you hit it.

Official Angular documentation about the slice pipe:

https://angular.io/api/common/SlicePipe

Point 2:

This one I wouldn’t solve by putting the entire item in the navparams, but by using a list of data set in the provider which you can reach from your detailpage.

Let’s say I have a list:

  • item 1
  • item 2
  • item 3
    When I click item one, then I’m on the detailpage. Now I want to navigate to item 2 without going back to the listpage.

instead of putting the entire item { item: item } into the navParams, only push the items index and keep the items in a provider instead of in the page. Now you can do this in your detailpage: this.detail_item = this.myDataProvider.items[index] . If you want to load the next item into your detailpage, simply add 1 to the index, or in case you want to ga back subtact 1. Make sure you don’t go out of the list’s reach (i.e. this.myDataProvider.items[-1] or something like that.

Point 3:

Use Ionic’s storage provider which you can find here.

Use the items unique ID als key in your storage. Something like this when I’ve opened an items detailpage:

setInStorage(key: string, value: boolean) {
    const identifier = 'seen_' + key;
    this.storage.set(identifier, value);
}

Now next time when you load your list, try to get the items from your storage:


getFromStorage(key) {
    const identifier = 'seen_' + key;
    this.storage.get(identifier).then(
       (result) => {
          if (!!result) ......
      }
   )
}

Point 4:

You’ve figured this one out yourself :-).

Please note I have wrote this code from the top of my head, and haven’t tested it. It’s just for you to get an understanding on how to achieve what you want.

Thanks for solving all the points, I am somehow confused in point two; below is my ts which loads data from my provider:
Kindly let me know what to modify and what to write. i have comment areas i think I should touch.

import { DataProvider } from "../../providers/data/data";


@IonicPage()
@Component({
  selector: 'page-lessondetail',
  templateUrl: 'lessondetail.html',
})
export class LessondetailPage {

  public lesson ={
    Lesson:"",
    Data:"",
  }
  ID:number;
  lessons:Lessons[];

  constructor(public data: DataProvider, public navCtrl: NavController, public navParams: NavParams) {
  
    data.getData().subscribe(lists => {
      console.log("details page dat are here", lists);
      this.lessons = lists;
    });    //is there anything to modify here?

  
  }



  getNext(){
    this.lessons....  //( should be written here to get the next content)

  }

  goBack() {
    console.log('i went back')
    this.navCtrl.pop();
    }


    
}



interface Lessons{
  id: number,
  Data:string,
  Lesson:string,
 }

What I’ve assumed is that you fetch your data in the page with all your lessons, let’s say lessonsPage. Instead of settings this.lessons, save the list of lessons into your dataprovider. Create lessons:Lessons[] in your dataProvider instead of your lessonsPage.

There you should do something like this:

data.getData().subscribe(lists => {
  this.data.lessons = lists;
});

Now in your detailPage, you shouldn’t need to subscribe anymore, but you can do something like this if you pass the index through the navparams from your lessonspage:

this.start_index = navParams.get('index');

and then set your detail lesson like this:

this.active_lesson = this.data.lessons[this.start_index];

thanks a lot for your help.
Seems funny how i got this all mixed up;
here is my provider .ts

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';


@Injectable()
export class DataProvider {

  private url: string = "http://localhost:8100/assets/data/lesson.json";


  constructor(public http: Http) {
    console.log('Hi am provider');
  }

  
  getData(){
    return this.http.get(this.url)
    .map(res => res.json())
    
  }

And here is my lesson .ts;

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { DataProvider } from "../../providers/data/data";
import { LessondetailPage } from '../lessondetail/lessondetail';
import { SlicePipe } from "@angular/common";


@IonicPage()
@Component({
  selector: 'page-lessondata',
  templateUrl: 'lessondata.html',
  providers: [DataProvider]
})
export class LessondataPage {

  ID:number;
  lessons:Lessons[];
  private lessondetail;

  constructor(public data: DataProvider, public navCtrl: NavController, public navParams: NavParams) {

    data.getData().subscribe(lists => {
      console.log("lessons are here", lists);
      this.lessons = lists;
    });
    this.lessondetail = LessondetailPage;
    
  }

  loadLesson(lesson){
    console.log(lesson);
    this.navCtrl.push(this.lessondetail, {lesson:lesson})
  }
}


interface Lessons{
  id: number,
  Data:string,
  Lesson:string,
 }

and my details .ts

import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { DataProvider } from "../../providers/data/data";

@IonicPage()
@Component({
  selector: 'page-lessondetail',
  templateUrl: 'lessondetail.html',
})
export class LessondetailPage {

  public lesson ={
    Lesson:"",
    Data:"",
  }
  ID:number;
  lessons:Lessons[]; // the interface blow: I was trying to bring data in here which is wrong based on you previous solution

  constructor(public data: DataProvider, public navCtrl: NavController, public navParams: NavParams) {
  
    data.getData().subscribe(lists => {
      console.log("details page dat are here", lists);
      this.lessons = lists;
    }); //constructed my provider to data, and have loaded data from provider to this details page also, of which i assume wrong approach too

    this.lesson = navParams.data.lesson;

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LessondetailPage');
  }

  getNext(){
    this.lessons  //I beleive to write the "next" function here so user can jump into next data while still on this detail page.
    
  }

  goBack() {
    console.log('i went back')
    this.navCtrl.pop();
    }


    
}



interface Lessons{
  id: number,
  Data:string,
  Lesson:string,
 }

I appreciate your assistance so far
Sorry for me being a dummy on this one

Haha okay… Well it’s a good try though. Here are some alterations which should make it more clear. I didn’t rewrite everything, because I think it’s good to learn some if this stuff on your own. Check out the differences:

provider.ts:

import { Injectable } from '@angular/core';
import { Http, Headers } from '@angular/http';
import 'rxjs/add/operator/map';


@Injectable()
export class DataProvider {

  private url: string = "http://localhost:8100/assets/data/lesson.json";
  // lesson should be a global interface if you reuse it
  public lesson ={
    Lesson:"",
    Data:"",
  }
  public lessons: Lesson[];

  constructor(public http: Http) {
    console.log('Hi am provider');
  }

  
  getData(){
    return this.http.get(this.url)
    .map(res => res.json())
    
  }


Your lessons.ts:

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { DataProvider } from "../../providers/data/data";
import { LessondetailPage } from '../lessondetail/lessondetail';


@IonicPage()
@Component({
  selector: 'page-lessondata',
  templateUrl: 'lessondata.html'
})
export class LessondataPage {

  ID:number;


  constructor(public data: DataProvider, public navCtrl: NavController, public navParams: NavParams) {

    data.getData().subscribe(lists => {
      console.log("lessons are here", lists);
      this.data.lessons = lists; // in your template you should now loop over data.lessons instead of lessons
    });    
  }
  // pass the index instead of the entire lesson, push it to the detail page so it nows where to start
  loadLesson(index) {
    this.navCtrl.push(LessondetailPage, {index: index})
  }
}

and your detailpage should then look something like this:

import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { DataProvider } from "../../providers/data/data";

@IonicPage()
@Component({
  selector: 'page-lessondetail',
  templateUrl: 'lessondetail.html',
})
export class LessondetailPage {

  public lesson ={
    Lesson:"",
    Data:"",
  }


  constructor(public data: DataProvider, public navCtrl: NavController, public navParams: NavParams) {
    
   let start_at_lesson = navParams.get('index');

    this.lesson = this.data.lessons[start_at_lesson]

  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad LessondetailPage');
  }

  getNext(){

      //I beleive to write the "next" function here so user can jump into next data while still on this detail page.
     // JUP, correct.
  }

  goBack() {
    console.log('i went back')
    this.navCtrl.pop();
    }


    
}

Thank you very much for this i will get back on how it goes.

Luuckschoen thanks a lot,
I still can’t get this done, had about an hour on a shame i can’t come up with the goal.
I never thought this could be difficult until now.
so far my view reads

    <ion-item *ngFor="let lesson of lessons | slice:0:10">

<button ion-button (click)="loadLesson(lesson)" full color="primary">{{ lesson.Lesson }}</button>
  </ion-item>

working well, but if I change the ts from

    data.getData().subscribe(lists => {
      console.log("lessons are here", lists);
      this.lessons = lists;
    });

to

    data.getData().subscribe(lists => {
      console.log("lessons are here", lists);
      this.data.lessons = lists;
    });

i can’t see any object on view (but will see data on console from “lists” above).

also in the lesson list;

 loadLesson(index){
    console.log('I loaded lesson', index);
    this.navCtrl.push(LessondetailPage, {index: index})
  }

returns an "‘undifined’ of undefine error"
i have made so many efforts that i can’t explain here still a hard-luck for me.

Okay, how does your lessons HTML look like?