0

I'm working on an ionic app, which I would like to integrate with firebase. I have the following code in my home.ts file:

export class HomePage {
  UHSGetMonths$: Observable < any[] > ;

  constructor(public navCtrl: NavController,
    public platform: Platform,
    private screenOrientation: ScreenOrientation,
    private UHSMonths: UHSGetMonthsService,
    public actionSheetCtrl: ActionSheetController,
    private localNotifications: LocalNotifications,
    public alertCtrl: AlertController) {

    this.platform.ready().then((ready) => {
      this.localNotifications.on('tap', (notification, state) => {
        let json = JSON.parse(notification.data);

        let alert = this.alertCtrl.create({
          title: notification.title,
          subTitle: json.fullMsq
        });
        alert.present();
      });
    });

    //this.screenOrientation.lock(this.screenOrientation.ORIENTATIONS.PORTRAIT);

    this.UHSGetMonths$ = this.UHSMonths
      .getUHSMonthsList() // DB LIST
      .snapshotChanges() // Give access to both Key and Value
      .map(changes => {

        return changes.map(c => ({
          key: c.payload.key,
          ...c.payload.val(),
        }));
      });
  }
}

I can successfully retrieve the data in my template files but how do get access a value in firebase database from the home.ts? In Firebase, I have meeting names and times for each month. E.g. for July, the team briefing takes place at 10am. How can I get the value 10am to use and manipulate in my home.ts?

Thanks

Firebase JSON file snippet:

[ { "days" : [ { "StaffBriefing" : "10:00", "Team A Meeting" : "11:30", "Team B Meeting" : "13:00", "Team C Meeting" : "15:30", "Date" : "01" }, { "StaffBriefing" : "14:00", "Team A Meeting" : "12:45", "Team B Meeting" : "14:00", "Team C Meeting" : "16:30", "Date" : "02" }, { "StaffBriefing" : "09:00", "Team A Meeting" : "14:00", "Team B Meeting" : "11:00", "Team C Meeting" : "15:30", "Date" : "03" } ], "monthName" : "January" } ]

Update - 03/08/2018

Yes, I added the subscription code after the this.UHSGetMonths$. However, the following code worked:

`this.JubileeMonths
  .getJubileeMonthsList() // DB LIST
  .valueChanges()
  .subscribe(data => {
    console.log(data);
 });`

And the console.log(data) displays:

enter image description here

If I do console.log(data[0]); I get this, which is fine.

enter image description here

However, If I try doing console.log(data[0].monthName); I get an error in my code editor (Atom) i.e. **Property 'monthName' does not exist on type '{}'` but in the console I get the correct value of January.

enter image description here

Why the error in the code editor or am I doing this all wrong?

Thanks.

UHSGetMonthsService

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import * as moment from 'moment';

    @Injectable()
    export class UHSGetMonthsService {
    private UHSGetMonthsRef$ = this.fbDB.list('UHS/Calendar/months');

      constructor(private fbDB: AngularFireDatabase) {

      }

      getUHSMonthsList() {
        return this.UHSGetMonthsRef$;
      }

    }      
GreenDome
  • 277
  • 2
  • 4
  • 15
  • Did you read the [docs](https://firebase.google.com/docs/database/web/read-and-write)? – Joseph Webber Jul 31 '18 at 12:16
  • Yes, I've had a look at docs and youtube tutorials but can't seem to understand how to do this. – GreenDome Jul 31 '18 at 15:49
  • What part is confusing you? The [Firebase docs](https://firebase.google.com/docs/database/web/read-and-write) are pretty straightforward when it comes to explaining how to read data. – Joseph Webber Jul 31 '18 at 16:02
  • Well, I pretty new to Firebase. May be an example on how to retrieve data from within home.ts would help. As mentioned, I can retrieve data from template files just can't figure out how to access a value using a key. I understand that .snapshotChanges() gives me access to both Key and Value but how do I use this with the home.ts file? Thanks – GreenDome Jul 31 '18 at 22:49
  • `snapshotChanges()` is for an `AngularFirestoreCollection` which is a part of angularfire2. I thought you were asking how to get data with firebase, my apologies. – Joseph Webber Aug 01 '18 at 12:20
  • I've added a snippet of the JSON from Firebase. From my home.ts file, I would like to access for example the `Team C` meeting time for `Date 2` object. – GreenDome Aug 01 '18 at 14:24
  • What does `UHSGetMonthsService` look like? – Joseph Webber Aug 03 '18 at 18:37
  • I've updated the post with `UHSGetMonthsService ` code. – GreenDome Aug 03 '18 at 22:47
  • Check my updated answer. – Joseph Webber Aug 04 '18 at 13:29
  • I tired the updated code but still getting the same error: **Property 'days' does not exist on type '{}'**. Strange... – GreenDome Aug 04 '18 at 19:07
  • 1
    Try putting the interface on the subscription's return value as well. `.subscribe((data: Month[]) => {`. You'll have to import `Month` from `UHSGetMonthsService`. Speaking of which, why do you have an entire service just to return a simple list reference? – Joseph Webber Aug 05 '18 at 05:07
  • That worked! thank you so much. The service will return additional stuff at later date. Just keeping it simple for now, until I get this issue sorted. Many thanks. – GreenDome Aug 05 '18 at 14:57
  • 1
    I recommend storing your interfaces in a single directory, each in their own file to keep them organized so you'll always know where to import them from. – Joseph Webber Aug 06 '18 at 04:02

1 Answers1

1

Given your database structure, you could do this after UHSGetMonths$ is set:

this.UHSGetMonths$
  .subscribe(months => {
    if (months && months.length) {
      let month = months.find(m => m.monthName === 'January');
      let day = month.days.find(d => d.Date === '02');
      console.log(day['Team C Meeting']);
    }
  });

If you wanted to get the current month's name for the .find(), you'd need to either use this post's solution or momentjs.
If you wanted to get the current day of the month, you can use new Date().getDate() or momentjs again.

Update:

You're getting the error because you haven't defined the "shape" of the return data, so as far as your IDE knows, it's just a generic object. To fix this, create an interface that matches what the data looks like and use it on your list reference.

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import * as moment from 'moment';

export interface Month {
  monthName: string;
  days: any[];
}

@Injectable()
export class UHSGetMonthsService {
private UHSGetMonthsRef = this.fbDB.list<Month>('UHS/Calendar/months');

  constructor(private fbDB: AngularFireDatabase) {
  }

  getUHSMonthsList() {
    return this.UHSGetMonthsRef;
  }
}
Joseph Webber
  • 2,010
  • 1
  • 19
  • 38
  • With this I get: `Uncaught (in promise): TypeError: Cannot read property 'subscribe' of undefined`. Just wondering, If `snapshotChanges()` gives access to both Key and Value then how can I use the key to retrieve its value? – GreenDome Aug 02 '18 at 22:09
  • Did you add the subscription code _after_ the code where you set `this.UHSGetMonths$` to an Observable? The key and value are both returned at the same time with `.snapshotChanges()`, you don't need to re-query for it, that would be redundant. – Joseph Webber Aug 02 '18 at 23:22
  • I have edited my post with additional details. Please see the part: **Update - 03/08/2018**. Thanks for your assistance, its appreciated. – GreenDome Aug 03 '18 at 18:30