This computed property lastSeenString
used to be working for me:
export class User {
public lastSeen?: Date;
private _lastSeenString?:string = "";
get lastSeenString():string {
return Time.timeSince(this.lastSeen);
}
}
But now lastSeenString
returns ""
. The return
statement in the getter is never called. How come? lastSeen
is populated.
client:
it('Displays the user\'s "last seen"', () => {
component.user.lastSeen = new Date();
fixture.detectChanges();
expect(component.user.lastSeenString).toBe("less than a minute ago");
expect(page.lastSeen.innerText).toBe("last seen less than a minute ago");
});
My typescript compiles to es5
. Why does code inside the getter not execute?
Time class which is supposed to get executed but doesn't:
export class Time {
public static timeSince(date: Date) {
let start = +new Date();
let elapsed = +new Date() - start;
var seconds = Math.floor((elapsed) / 1000);
// var seconds = Math.floor((new Date() - +date) / 1000);
//var seconds = Math.floor(((new Date().getTime()/1000) - +date))
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 "less than a minute ago";
}
}
actual implementation of the User class:
export var SERENA: User = {
id: 1,
lastSeenString: "",
lastSeen: new Date("October 13, 2016 11:13:00"),
badges: ["active User", "helper"],
memberSince: new Date("October 13, 2014")
}
I see the implementation has lastSeenString = ""
, however I thought that would trigger the getter rather than just return ""
.
Update: I'm pretty sure it must be to do with just exporting that JSON object and calling it a User
. I think I must have to new it up.
The getter is defined on the prototype of User
- i.e. as part of the class itself. You need to build your instance using that class (e.g. with new User()
) for the getter to work.
Currently you just build a vanilla JavaScript object, and then tell TypeScript that it's the same shape as a real User object. That passes type checking, because it is the same shape - reading any field on it will return values of the same type that you'd be expecting from a real User object - but that doesn't tell you anything about the underlying behaviour of those fields.
In my case, I was getting object data from the network as JSON. Then assigned the data like this:
let newUser = Object.assign(new User(), data)
I could access all of the public data and functions, but couldn’t access functions, getters, setters for objects inside this object. So I had no access to private data even though I could print them out.
class User {
name: string
state: UserState
}
class UserState {
private _stateInfo: string
getter()......
}
So I can access name, and can print out the data of state
. But can’t access functions inside state
.
The way to solve this is to initialize new UserState
object when passing the data for User
object.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With