typeError: Cannot read property function of undefined

Hello, i have some datetimes stored on a database 2018-06-12 04:24:26 , i want to get this datetime in format like xxx minutes/seconds/hours/days ago, here’s what i did:

function to convert datetime:

timeSince(datez) {
    var nowdate: any= new Date();
    var seconds = Math.floor((nowdate - datez) / 1000);
  
    var interval = Math.floor(seconds / 31536000);
  
    if (interval > 1) {
      return interval + " years";
    }
    interval = Math.floor(seconds / 2592000);
    if (interval > 1) {
      return interval + " months";
    }
    interval = Math.floor(seconds / 86400);
    if (interval > 1) {
      return interval + " days";
    }
    interval = Math.floor(seconds / 3600);
    if (interval > 1) {
      return interval + " hours";
    }
    interval = Math.floor(seconds / 60);
    if (interval > 1) {
      return interval + " minutes";
    }
    return Math.floor(seconds) + " seconds";
  }

**function to get data from the database and putting the datetime in the format " xxx minutes ago" **:

public async getNotifs(){
    return this.authServiceProvider.getDataz("getNotifications/"+this.myAccountId)
    .then(data => {
      this.notifData=data;
      this.notifData.forEach(function (Data) {
       console.log(this.timeSince(Data.datetime));
      }); 
      
    }, (err) => {
      console.log(err);
    });
  }

Here’s my error log:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'timeSince' of undefined
TypeError: Cannot read property 'timeSince' of undefined
    at main.js:470
    at Array.forEach (<anonymous>)
    at main.js:469
    at t.invoke (polyfills.js:3)
    at Object.onInvoke (vendor.js:4982)
    at t.invoke (polyfills.js:3)
    at r.run (polyfills.js:3)
    at polyfills.js:3
    at t.invokeTask (polyfills.js:3)
    at Object.onInvokeTask (vendor.js:4973)
    at main.js:470
    at Array.forEach (<anonymous>)
    at main.js:469
    at t.invoke (polyfills.js:3)
    at Object.onInvoke (vendor.js:4982)
    at t.invoke (polyfills.js:3)
    at r.run (polyfills.js:3)
    at polyfills.js:3
    at t.invokeTask (polyfills.js:3)
    at Object.onInvokeTask (vendor.js:4973)
    at c (polyfills.js:3)
    at polyfills.js:3
    at polyfills.js:3
    at t.invoke (polyfills.js:3)
    at Object.onInvoke (vendor.js:4982)
    at t.invoke (polyfills.js:3)
    at r.run (polyfills.js:3)
    at polyfills.js:3
    at t.invokeTask (polyfills.js:3)
    at Object.onInvokeTask (vendor.js:4973)

Did you actually debug this? Put a breakpoint in there and see what this is referring to in the context you are attempting to access timeSince.

It absolutely does not point to the class that has the timeSince method on it.

Instead it points to the anonymous function you created as a callback to forEach.

1 Like

Instead of reinventing the wheel, how about just using date-fns/distanceInWordsToNow?

1 Like

I think you’re right, do you have any idea of how to fix that ?

Im app is in french i wanna display the “2 minutes ago” in french, and im using a lot of external libraries already dont wanna use anymore x)

let distanceInWordsToNow = require("date-fns/distanceInWordsToNow");
let dateLocaleFr = require("date-fns/locale/fr");

distanceInWordsToNow(targetDate, {locale: dateLocaleFr});

date-fns is one of the lightest out there. It is specifically designed to include only the bare minimum functionality you use. I would also bet that it is (a) more accurate and complete and (b) probably smaller in terms of code footprint than what you would come up with.

@Fragan I’ve seen more than once errors about this incorrectly scoped. As @rlouie pointed out:

Instead it points to the anonymous function you created as a callback to forEach.

Try to change:

this.notifData.forEach(function (Data) {
    console.log(this.timeSince(Data.datetime));
});

to

this.notifData.forEach(data => {
    console.log(this.timeSince(data.datetime));
});

This way you will use arrow functions to make sure this is correctly scoped. Also, certify that the methods timeSince() and getNotifs() are in the same class.

Two factors influenced the introduction of arrow functions: shorter functions and non-binding of this.

How should i use this in ionic ?

import distanceInWordsToNow from 'date-fns';
import fr from 'date-fns/locale/fr';

Im i doin imports right ? Can you give me and example of how to import and how to use it in Ionic ?

import * as "myWishedVar" from 'date-fns'

// ...

myWishedVar.distanceInWordsToNow(myArgs)