Lifelog

Write 100 words a day, every day, towards your goals.

Added profile images to /notifications and /_goal pages

• For /notifications page: Used the same approach of using forEach() and push() to match-merge `accounts` array to `notifications` array, in both initial data fetch `fetchNotifs()` and when updating notif class `updateNotifClass()`

• For /_goal pages: Used `try... catch` to prevent error page, in case there's a user without an account and GET request to findOne account fails

• Did you know? In Nuxt.js when using the nuxt/axios plugin, you can also disable the progress bar in specific requests using the progress option in an inline request configuration: https://axios.nuxtjs.org/options/#progress

`this.$axios.$get('URL', { progress: false })`

Day 184 - Decision killers: Find 1 decision that removes 100 decisions https://golifelog.com/posts/decision-killers-find-1-decision-that-removes-100-decisions-1625293838922

Tim Ferriss talked about why he won’t be reading any new books in 2020 in his blog post. But the idea that caught my eye was his title:

Finding the one decision that removes 100 decisions

This is a great heuristic to add to my goal of 1% compounding. In matters big or small, life-changing or mundane, find that 1 upstream decision that removes 100 decisions downstream.

Tim elaborates:

In my life, where am I making decisions or saying “yes” out of guilt? Can I create a blanket policy that makes it easier for me to say “no”?

In what areas am I making a lot of decisions, or sending a lot of communication? Are they concentrated anywhere? Can I create a blanket policy that makes it easier for other people to make those decisions?

In what areas am I making a lot of decisions, or sending a lot of communication? Are they concentrated anywhere? Can I create a blanket policy that entirely removes the need to make those decisions?

😅COMPLETED adding profile images for /community page! Had to re-refactor the code again for First Joined, Top, Best, Most Streaks leaderboards

After discovering the more performant approach of using forEach() and push() to add `accounts` details to the original data arrays without having to change the data structure too much, I refactored the code for the previous leaderboards YET AGAIN.

But glad to do so, I guess. Now the code is cleaner, more readable, and more consistent across the methods for each leaderboard. 🤷‍♂️

And I'm FINALLY done with adding profile images to the /community page! Wow this took a week at least!

😅 Next: adding profile images to /notifications, /_goal, /roadmap, posts/_slug, home pg

Day 183 - July https://golifelog.com/posts/july-1625209957787

Looking forward to a fruitfully busy July:

• A training workshop for a polytechnic
• A consultancy project for a government client
• Potential frequent mini-workshops for another government client

So July will be about exercising my gratitude for being able to stay self-employed, by doing these projects well. That’s really my main mission for the month.

But even while I get to do my day job, I’m allocating my early mornings (5-9am) for my other projects, like Lifelog:

• Launching profile images on Lifelog - had spent the past 2 weeks on it, and grossly underestimated the work involved!
• More content marketing for Lifelog - getting back to some regular coding:content candance
• Doing something about my yet-to-be-launched new project Grublink - doing something new had always been life-giving.

Overall, my July goals and plans don’t look like much. It sounds so normal. But frankly, after months of anxiety and chaos, normal actually sounds pretty good to me.

💪 YASSS! Found the best way to merge accounts array with comments and posts array for Most Comments and Most Posts leaderboard on /community page

The most performant way to merge the accounts array with all the leaderboards on the /community page is to use forEach() and push() after using Object.entries() but before splice.sort.slice()

const sortedArr = Object.entries(sorted)

const sortedArrWithAcc = []
sortedArr.forEach(function (element) {
sortedArrWithAcc.push({
id: element[0],
postsArray: element[1],
account: accountsall.find(
(e) => e.author.id === parseInt(element[0])
),
})
})
this.mostPosts = sortedArrWithAcc
.splice(0, 99999)
.sort((a, b) => b.postsArray.length - a.postsArray.length)
.slice(0, 99999)

Day 182 - Things I started seeing as essential https://golifelog.com/posts/things-i-started-seeing-as-essential-1625126180689

What are some things that you didn’t used to see as essential, but after you started doing them, could no longer live without now?

• Good quality sleep
• Fats and protein
• Some form of daily diet restriction
• Supplements
• Travel
• Habit systems
• Creating new stuff
• Writing regularly/daily
• Frequent me-time for deep work
• Money - crazy right how could I?

Solved it! Merged accounts array and goals array for Most Goals leaderboard on /community page

Can't use the previous code for merging streaks for the goals array, had to think of something new/creative for the Most Goals leaderboard, fetchMostGoals() function

Ended up flipping the approach, merging each goal (within the raw goals array) with accounts data first using forEach() and push(), then doing the usual of nesting all goals per author together into the data array (`this.mostGoals`) for rendering using for loop and push().

Day 181 - June wrap-up https://golifelog.com/posts/june-wrap-up-1625033813398

Overall an uneventful June, thought the uneventful part was much appreciated.

Revenue:
– MRR: $50
– One-off revenue: $105

Added profile image to Best Streaks and Most Streaks in /community page

Wow this feature is turning out harder than expected, and a lot more work across multiple files. Poor tech estimation again! Need to get better at this.

• Optimised First Joined and Top Streaks leaderboards (using the fetchCurrentStreaks() function) to use data from asyncData() instead, thus making first paint faster
• removed fetchAccAll() from mounted() since no longer necessary
• Had to match profileImg to authors in fetchLongestStreaks() fetchMostStreaks() functions

Next: wrangling with the code for Most Goals, Most Comments and Most Posts!

Day 180 - Fear-setting https://golifelog.com/posts/fear-setting-1624934406122

“I’ve had a lot of worries in my life, most of which never happened.” - Mark Twain

Fear-setting: It’s like a darker but necessary twin to goal setting. Just as we plan for goals by imagining the best possible future, we face our fears by identifying it as a worse-off possible future. Both require planning. Both needs a hearty dose of grounded reality, versus imagined pain or rewards.

Set your fears, to set them free.

🎉 WOOHOO solved it! Finally found a condition to conditionally render the profile images of users without the content-type "account" and `.profileImg`

My problem had been I had 3 types of data, and I want to show different profile image with different data.

- user with account and profile image url - render `streak.profileImg`

- user with account but no profile image url, use `streak.author.id` to render robovatar

- user without account, use `streak.author` (notice it's different!) to render robovatar

I could v-if the first 2 using `v-if="streak.profileImg"` and `v-else-if="streak.profileImg == '' || streak.profileImg == null" respectively, but the 3rd one somehow doesnt work using `v-else` or `v-else-if="!streak.profileImg"`.

In the end for 3rd one I found a hack:

`v-if="typeof `${streak.author}` === 'string'"` because only for users without account their `author` data is a string(`"11"`), not an `Object`.

Day 179 - Things I stopped seeing as essential https://golifelog.com/posts/things-i-stopped-seeing-as-essential-1624872462099

What is something that for a long time you thought was essential, but once you stopped doing it, you realized everything was just fine without it? ~ @stephsmithio

Things I stopped seeing as essential:

A job (being employed)
Giving birth in a hospital
Carbs - bread, rice, noodles
Being polite and nice
Finding your one true passion
Being a night owl
Having children (but I had one anyway)
Getting married (but got married anyway)
......

Working on changing my mind about it:
Shampoo
Being lazy
Not equating hard work with self-worth
......
Jason Leow Author

yeah, thats my understanding too. The oils are there for a purpose, but our modern habits remove it too often. Will experiment and see if this is true!

0 Likes
Carl Poppa 🛸

yes i've heard that our natural oils are what's best for our hair. i used to shower and shampoo twice a day - i can't afford not to. working in a restaurant and sweating for long hours… Now it's reduced to once a day, no longer such a sweaty boy haha

0 Likes

😵 Cont'd debugging of profile image on /community page

Can't believe I spent the whole day trying to debug this bugger! Weird data rendering bug on Vue.

---

When I tried to access .profileImg data in my template, it renders as [object Object]. Right now, the profile images for is rendering `...roboharsh.org/[object Object]` in the template... why???

Day 178 - Underestimate your past, overestimate your future https://golifelog.com/posts/underestimate-your-past-overestimate-your-future-1624762440269

Say as he said, “I still understand little, but I’m capable of accomplishing a lot.”

So now I should instead say, “Thinking back, I don’t think I can do that much, but I believe I’m capable of achieving a lot, despite that.”

Humble about past, conservative about your previous achievements, yet optimistic about the future, bullish about what you can achieve.

It might not be as much as I thought, but it can still be a lot nonetheless.

😣 Realised the hard work for the past week is moot, because of one tiny detail I overlooked

My solution for profile images on the /community page only works because I assumed the index position for my accDetailsAll and author.id are aligned. But they are not in the production db, because I had deleted users before. For index position 4 now has author id of 10. The hack of using `....- 1` doesn't work anymore.

Back to the drawing board!

Spent the whole morning trying to using a method in a v-if nested within a v-for
`v-if="getProfileImg(streak.author)"`
but it ended up creating an infinite loop 😵

Will try map() within a method instead and push() the profileImg data to the array for v-for

Day 177 - Content - making friends at scale https://golifelog.com/posts/content-making-friends-at-scale-1624677415915

Just as code scales your productivity and your work, helping you automate tasks or do them faster/easier, content scales your networking, helping you make friends and connect to business acquaintances while you sleep, at scale.

Fixed data rendering issue of profile image on profile page

• Added additional v-if="accDetails" to
profile image, in case a particular account doesn't exist in the data table - to prevent error when at the next v-if="accDetails.profileImg lower down the template (if account doesn't exist, accDetails would be undefined and .profileImg would be trying to read from an undefined variable, which will result in an error)

• Added additional v-else to show robo avatar if account indeed doesn't exist

• Overall, the logic looks like this:
--- v-if - if account exists
------ v-if - if image is null or empty, show robo
------ v-else - if image exists, show image
--- v-else - if account doesn't exist, show robo

• also added try {} catch {} to the function for the accDetails endpoint to prevent error from stopping the page from rendering

Fixed profile image rendering bugs/edge cases on profile page, blog

I'd been mistaken how javascript operators work, like == ||

The logic: if variable is either null or empty, then do this.

❌ v-if="accDetails.profileImg == null || ''"
❌ v-if="accDetails.profileImg == (null || '')"
✅ v-if="accDetails.profileImg == null || accDetails.profileImg == ''"

🤜💥🐞💥🤛 Solved it! Thank you @keenen @yuyu for the lifesaver help!

Solution: Had to wrap a v-if to check if accDetailsAll[streak.author] exists before checking with another v-if for .profileImg

------

Penning down my approach for this feature, for future reference:
• accDetailsAll will contain all authors details. Their position in the index will match their author id.
• streaks only return authors with streaks, but it comes with author id too.
• so by accDetailsAll[streak.author - 1], I'm using the streak author id to find the correct index position of the author details in the array
• Downside of this approach is: if a user delete his account, the index position of accDetailsAll will be messed up. Would PostgresQL skip id numbers too in their tables?

Day 176 - Stop at 80% https://golifelog.com/posts/stop-at-80percent-1624608689441

🤬 Spent the entire day debugging an error, but no luck today

Why does this happen (Vue.js)?

I get a good response when i console log a variable in my mounted() function:

console.log(this.accDetailsAll[1].profileImg)

But when I access the same in my template in the html, it gives an error "Cannot read property 'profileImg' of undefined"

{{ accDetailsAll[1].profileImg }}

----

It checks if the value exists before rendering it. So when the method on mounted() finished, data becomes available, and it will get printed. On load, before data is available it will be hidden. Because of async function, that array is empty when it’s loaded. Async doesn’t wait.. it lets your code run. It works on the console because you use await which wait for the call to finish. But on template, you tried to access it directly.

Another way if you don’t want to add v-if is to construct your array object in data when you initialize it:
accDetailsAll: [ profileImg: '' ]

So the structure is always there. But if you work with API, you don’t want to prepare all the attributes on your component. This construct approach will be hard to maintain, because one more thing to update if the API changes. Using v-if is better.

I thought because I added await in the function, when i access it in the template, it will wait till the data is loaded..
It will wait in the function.. not on the template. If you use asyncData, then this is ok because it’s processed before page is loaded.

Day 175 - Manage energy, not time https://golifelog.com/posts/manage-energy-not-time-1624502421673

One hour is one hour is one hour. But how productive you are within that one hour, really comes down to the energy level you bring to the tasks within that hour.

One hour immediately after you wake up feeling fresh and alert from a good night’s sleep, is a very different one hour after a heavy lunch of too much spaghetti and meatballs.

Energy management > time management

Productivity is not about how you manage your time, but how you manage your energy.

Day 174 - Have you found a fit? https://golifelog.com/posts/have-you-found-a-fit-1624428779449

Useful checklist:

Product-market fit: When a product is providing value to a big enough group of customers.

Founder-market fit / Product-founder fit: When the experience and expertise of a founder is suited to creating a product for the relevant market.

Business model-market fit: When the business model of a product gains traction by showing consistent revenue retention, and scalable sales/marketing/customer acquisition.

Founder-future fit: When the insight/vision that a founder has for the future is right on aligned to present trends of disruption.

Day 173 - Wake windows https://golifelog.com/posts/wake-windows-1624334332590

Ryan Glass

Serious commitment - much respect!

0 Likes
Jason Leow Author

yeah it is, isn't it? would never have imagined doing this just a year ago. always thought i was a night owl!

0 Likes