How to print Json Files on Android page

the main problem I have when reading the books of the bible is that I do not understand very well how to organize json files:

[{
	"abbrev": "gn",
	"book": "Genesis",
	"chapters": [{
		"1": {
			"1": "At the first God made the heaven and the earth.",
			"2": "And the earth was waste and without form; and it was dark on the face of the deep: and the Spirit of God was moving on the face of the waters.",
			"3": "And God said, Let there be light: and there was light.",
			"4": "And God, looking on the light, saw that it was good: and God made a division between the light and the dark,",
			"5": "Naming the light, Day, and the dark, Night. And there was evening and there was morning, the first day.",
			"6": "And God said, Let there be a solid arch stretching over the waters, parting the waters from the waters.",
			"7": "And God made the arch for a division between the waters which were under the arch and those which were over it: and it was so."
		}
	}]
}]

I have already modified my hello files.

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Component(
{
  selector: 'page-hello-ionic',
  templateUrl: 'Hello-ionic.html'
}
)
export class HelloIonicPage 
{

  constructor(public navCtrl: NavController, public http: Http) 
  {        
         this.http.get('data/gif.json')
         .map(res =>{
         return res.json().categories.reduce((pre, cur) => {
            let prevResult = Number.isInteger(pre) ? pre : pre.recipes.length
            return Math.max(prevResult, cur.recipes.length);
        })
    })
    .subscribe(data => {
        console.log(data);
    });
  }
  
}

The problem is that I can not find how to print on my page the book of genesis of the json file that I showed you above,

<ion-header>
  <ion-navbar>
    <button ion-button menuToggle>
      <ion-icon name="menu"></ion-icon>
    </button>
    <ion-title>BIBLIA RV</ion-title>
  </ion-navbar>
</ion-header>


<ion-content>
    
</ion-content>

I have seen hundreds of tutorials but I have failed at all, if you have time available and would like to help me in this development, I would thank you infinitely.

I don’t know what on earth the recipe stuff is supposed to be doing in there, but I’m going to assume you’re sort of copying code you found from some other place and hoping that it will work. This is called cargo cult programming and doesn’t generally produce very helpful results.

The first step is always to define interfaces that represent the various units of your data. Books have names, chapters have verses, and so on. Especially if you’re planning to iterate across these things using *ngFor in your templates, it would be much more natural to switch to using arrays instead of objects:

[{
  "abbrev": "gn",
  "book": "Genesis",
  "chapters": [
    [
      "At the first God made the heaven and the earth.",
      "And the earth was waste and without form; and it was dark on the face of the deep: and the Spirit of God was moving on the face of the waters.",
      "And God said, Let there be light: and there was light.",
    ],
  ],
}]

Now we can model the domain like this:

export interface Chapter {
  verses: string[];
}

export interface Book {
  abbrev: string;
  book: string;
  chapters: Chapter[];
}

export interface Bible {
  books: Book[];
}
export class BibleService {
  ready: Promise<void>;
  bible: Bible;
  constructor(http: Http) {
    this.ready = http.get('data/gif.json').toPromise();
    this.ready.then(bible => this.bible = bible);
  }
}

export class TocPage {
  constructor(private _nav: NavController) {}
  gotoBook(ix): void { this._nav.push(BookPage, {ix: ix}); }
}

<button (click)="gotoBook(0)">Genesis</button>

export class BookPage {
  book: Book;
  constructor(np: NavParams, bible: BibleService) {
    let bookix = np.get('ix');
    this.book = bible.ready.then(() => this.book = bible.bible[bookix]);
  }
}

<h1>Book of {{book.book}}</h1>
<div *ngFor="let chapter of book.chapters; let cix = index">
  <h2>Chapter {{cix+1}}</h2>
  <div *ngFor="let verse of chapter.verses; let vix = index">
  {{vix+1}}. {{verse}}
  </div>
</div>
1 Like

Does this successfully output your JSON?

No, my books do not appear on the page, it’s as if nothing of what I do works.

I didn’t ask if it appears on the page, I asked if the console.log of data you have in your code actually outputs something useful to the console.

Yes, on the console I get the entire Json file, but nothing on the emulator page.

Modify my file and cheese in this way:…

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Component(
{
  selector: 'page-hello-ionic',
  templateUrl: 'Hello-ionic.html'
}
)
export class HelloIonicPage 
{

  constructor(public navCtrl: NavController, public http: Http) 
  {        
         this.http.get('https://raw.githubusercontent.com/Jhan321/Bible-RV/master/Biblia/rvres.json')
        .map(res => res.json()).subscribe(data => 
        {
            console.log(data);
        });
  }
}

Well, this means that you are successfully retreiving the file and putting it into data. That’s good.

Now you have to get that over to the template:
You need a class variable where you can put data. Have a look at the 'this.bible` of the code @rapropos posted. And the last step will be to iterate over this data structure in the template. But as a first step you can also just output the name of the book.

1 Like

You would help me to show the name of the book, I think with that I will do the rest.

Here is a program that might help you convert between the form you have now and the one I’m recommending. Save it to a file called bibleconv.js, and you can invoke it like so:

$ node bibleconv.js /path/to/existing/format.json > /path/to/new/format.json

let fs = require('fs');
fs.readFile(process.argv[2], 'utf8', (err, data) => {
  let inbound = JSON.parse(data);
  let outbound = inbound.map((book) => {
    let inchaps = book.chapters[0];
    let outchaps = [];
    for (let schapnum in inchaps) {
      let chapix = parseInt(schapnum) - 1;
      let verses = [];
      for (let sversenum in inchaps[schapnum]) {
        let vix = parseInt(sversenum) - 1;
        verses[vix] = inchaps[schapnum][sversenum];
      }
      outchaps[chapix] = verses;
    }
    book.chapters = outchaps;
    return book;
  });
  console.log(JSON.stringify(outbound));
});

I’m not 100% sure it will work out of the box, because I haven’t seen what the second chapter or book looks like, but it should be close enough for a starting point.

2 Likes