Read the statement by Michael Teeuw here.
Compliments module stops cycling compliments
-
Alright, my problem is that over a short period of time (5-10 updates) the default Compliments module will stop changing compliments. It simply displays the same compliment endlessly.
I decided to dig into the issue. I will spare you the troubleshooting process, but I found out that the Compliments module will append the ‘anytime’ compliment to the end of the existing
compliments
array. So thecompliments
array gets longer every time it is updated.The ‘anytime’ compliments are appended to the end of the
compliments
array, which grows the array indefinitely. The random compliment function works as intended, but if thecompliments
array has 10 ‘anytime’ compliments and 3 ‘afternoon’ compliments, there’s a high chance that a ‘anytime’ compliment will be chosen. The odds that an ‘anytime’ compliment will be chosen goes up every update.Specifically, I’ve found the issue to occur right when the compliments array is filled with compliments. What happens (in my case) is that the compliments that get added to the
compliments
array already includes the ‘anytime’ compliments. Then, a few lines later, the ‘anytime’ compliments are appended to the end of the now-filled compliments array.Why this happens is not clear to me at all. Looking at the code, the ‘afternoon’ compliments should be added to the compliments array, then the anytime compliments should be appended. The compliments array is initially set to null, and that works, but for some reason, when the ‘afternoon’ compliments are assigned to the compliments array, the anytime compliments are included. Again, this does not make sense. (It shouldn’t be doing that)
To illustrate what I am talking about, add the following lines right after the if-then-else loop that sets the compliments array.
Log.info("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); Log.info("COMPLIMENTS FROM FILE (afternoon): " + this.config.compliments.afternoon); Log.info("~~~~"); Log.info("COMPLIMENTS STORED IN COMPLIMENTS VARIABLE " + compliments);
Make sure you change ‘afternoon’ to whatever time of day it currently is. Then run `npm start dev’ and watch the console on the right side of the screen.
What I saw (in the dev console) was that
this.config.compliments.afternoon
displayed the correct compliments defined by the defaults or whatever external file I specified. However, thecompliments
array would somehow have the ‘anytime’ compliments in it. Every time the program updated thecompliments
array, there would be one more set of ‘anytime’ compliments at the end.Using the same method of displaying the array at different points of program, I found out that the
compliments
array is being set to null initially. I can’t for the life of me figure out why the ‘anytime’ compliments would get in there.To eliminate even more variables, I renamed my
~/MagicMirror
directory and downloaded and installed a new one. I put the lines above in thecompliments.js
file and I observed the same behavior.Hopefully, I explained this issue well enough that other people can understand. I also hope that this is a simple fix or mistake on my end. I would be glad to provide any extra info that might be needed. Thank you for any assistance.
-
@maxfarrior you’re right that is a bug.
The way javascript handles variables are usually call by value, but for objects (this includes arrays) it is call by reference.
So what happens in line 104 is the following: The variable compliments doesn’t get cloned, so that the values are equal. What happens is they are the same array and point to the same reference to the memory. That means in the following lines not only compliments get changed, also
this.config.compliments.afternoon
gets changed.So in the beginning your config looks like that
config: { compliments: { afternoon: ["I'm the only one here"], anytime: ["I'm getting repeated"] } }
after the first iteration it looks like this
config: { compliments: { afternoon: ["I'm the only one here", "I'm getting repeated"], anytime: ["I'm getting repeated"] } }
after the second
config: { compliments: { afternoon: ["I'm the only one here", "I'm getting repeated", "I'm getting repeated"], anytime: ["I'm getting repeated"] } }
and so on …
So to fix that, we have to create a real clone not only a pseudo one.
I already created a bugfix for that here
-
Awesome! Your explanation makes sense and I’m glad you were able to understand what I was saying and then make a fix.
First, can I go ahead and copy your fix into my code? I don’t see why not, but I thought I’d ask.
Second, am I really the first person to notice this? I feel like the behavior is pretty noticeable.
-
@maxfarrior It was merged in develop branch about an hour ago.
You can switch to develop branch by
git checkout develop
in the MagicMirror directory.I guess most people only use the standard compliments morning, afternoon and evening without anytime and weather, where the error not occurs.
-
Alright I will switch to the develop branch.
Very interesting. I’m glad the issue got resolved!