Jason Leow

Indie hacker, solopreneur | Creating a diverse portfolio of products + services.

Solved loading spinner issue where the spinner stops before data fetch is completed

Kudos to @keenen for this lightning tutorial! ⚡️

I was trying to create a loading spinner while the comments tab of the /community page fetches data (currently taking 5s due to massive data size! Will have to think abt optimization later), and I want the spinner to keep going till the data fetch is complete and rendered on page. How does one go abt tracking when the data fetching is finished, and to stop showing the spinner and show the data (on Vue/Nuxt)?

I tried defining an `isLoading: false` data attribute and then toggling it to true at the end of my function, but it didn't work. (Not sure why, could be because isLoading is shared in other functions which gets called. But changing to unique data objects like `commentsIsLoading` didn't work either)

As advised by Keenen, used `v-if="mostComments.length == 0"` in the end for the spinner template. Better to track the data object in question directly than defining a different one to toggle the spinner!

Added the spinner to 3 tabs - Most Goals, Most Comments, Most Posts

Side-note: `mostComments == null` doesn't work because I initialized it as an empty string in the beginning. Alternatively I can use using empty string in a pair of single quotes instead of null, like `v-if="mostComments = ''`

Ref:
Awesome loading spinners from https://tobiasahlin.com/spinkit/

Day 80 - Console logging as a way of work & life https://golifelog.com/posts/console-logging-as-a-way-of-work-and-life-1616286738929

Without a way to see how my inputs would lead to an expected output, it’s hard to do it well. No wonder my marketing efforts fell flat most of the time. So how can I console log this for marketing?

Analyze current data and find the right marketing problem to solve. Who’s my audience?
What’s working now w.r.t. marketing, no matter how tiny? Find them and repeat.
What’s not working? Find them and stop doing them.
What’s worth experimenting with? Research and test.
Break things down to solvable chunks. Start with a $100 MRR plan first.
What are the patterns and/or ordered steps to get to $100 MRR?
What inputs do I need each step along the way towards $100 MRR plan
What outputs should I expect at each step before moving on to the next?

Anything else I missed or could/should do?

Fixed home page data fetching errors in console.log

Hide functions behind if condition `isAuthenticated`, so that errors won't show in home page console.log if user not logged in yet.

Day 79 - On not recognising yourself, and switching pace on Lifelog https://golifelog.com/posts/on-not-recognising-yourself-and-switching-up-pace-on-lifelog-1616231090096

Looking back, it’s sooo fucking amazing how far I gotten from so little that I knew back then. I knew almost zero Javascript, and only a splattering of Vue.js. But now, I feel like I can legitimately say I enjoy coding. Bugs and issues that used to make me want to rage quit are now pretty manageable, even palatable (because it helps me learn more). How far things have turned from the days I constantly clashed with coding, going through the motions of the work only because I wanted the outcome. That dissonance would have been unhealthy and simply unsustainable.

It’s almost like I stepped out of this phase a different person, unrecognisable to my past self. Isn’t that what they say about growth?

I can go with that.
Jason T

You are really one of those that I saw keep up with your perseverance and push on! Still remember you were learning programming during the 200wad days… You have really come far :)

0 Likes
Jason Leow Author

Thanks @jasontxf ! Wow those days on 200wad openly struggling with coding… feels like so long ago now!

0 Likes

📺"Look mum, I'm on TV!"

Receiving the awards at SCS IT Leaders awards ceremony for all the COVID19-related tech for good products I made last year

Fixed bug in "you have written for the day" banner

As always, what I thought was easy usually ends up not. Assumed that the date-streaks package had a ready data variable to use to track if a user had written for the day. But ended up being inaccurate, possibly due to it calculating based on a 24h window. I didn't want to dive into the package to make changes, so decided to roll my own component that did this:

* fetch last/most recent post of logged in user from API endpoint using filter params `.......?author.id=${user}&_sort=id:DESC,published_at:DESC&_limit=1`
* convert timestamp of last post to a epoch/unix time Date object, using .getTime()
* using last post Date object, create another Date object of the following midnight in epoch time, using .setHours(24, 0, 0, 0)
* using previous midnight Date object, create another Date object of the following midnight after next in epoch time, using .setHours(24, 0, 0, 0)
* create another Date object for the current time in the user's browser, using Date.now()
* if next midnight is more than current time, then show "You have written for the day" success banner
* if next midnight is less than current time & midnight after next is more than current time, then show "Write now to maintain streak" warning banner
* if current time is more than midnight after next, then show nothing

☕️ Received my 2nd monthly subscriber - US$5/m

Joel Patrizio

Congrats Jason! 👏

0 Likes
Jason Leow Author

Thanks Joel!

0 Likes

🚀 Finally launched my social impact patronage project!

Help me help others, using tech for good.

See my crowdsourcing/-funding page here 👇🏻
https://www.buymeacoffee.com/jasonleowsg

Read more about it here 👇🏻
https://golifelog.com/posts/launching-my-social-impact-patronage-1616137024350

---

Please link me up with ideas or charities/NGOs who need tech help, or support financially by a monthly membership (to offset the costs of domain/web hosting).

Day 78 - Launching my social impact patronage https://golifelog.com/posts/launching-my-social-impact-patronage-1616137024350

https://www.buymeacoffee.com/jasonleowsg

🤝 HELP ME HELP OTHERS

If you like my content and products like Keto List Singapore, Grant Hunt, VisualAid, Public Design Vault or the other social good indie products I made, please consider supporting me:

— every month by becoming a patron member (click on 🔒Membership tab on the right), or

— buying me some one-off coffee (click on 🧡Support tab on the right).

I deeply enjoy making social good products, and I’ll get to do it frequently because of your kind support. Will be super grateful if you can help me help others!

The resources you provide will go towards building new social impact digital products, as well as maintaining the current ones w.r.t. domain names, web hosting, subscriptions for tools, etc.

Day 77 - Be boring to find your niche https://golifelog.com/posts/be-boring-to-find-your-niche-1616059411923

This one was hard to reconcile:

"Everyone wants to “find their niche” – barely anyone wants to repeat themselves every day." ~ @jackbutcher

Hard to reconcile because I know it’s true, yet I’m not willing to face the reality, that it can get really boring really fast to always repeat myself. And I don’t enjoy being naggy.

The reality is that even if I do know it, it’s difficult to exercise that level of self-awareness on a daily basis to see that my message might be new to some people, and that great ideas need constant reinforcement.

Easy to think, hard to act on. The simplest things tends to be the hardest to do, yet the most rewarding.

Created 2 new payment links for 6 mth Banner and Boosted ads for Blyss Foods

YAAASSS!!! Got the post goals edit/delete function working!

Avoiding v-model was an interesting departure to got me diving deeper into how Vue really works. In the end, it wasn't about all the fancy schmancy Javascript tricks of adding event listeners forEach checkbox and using the @change handler to track clicks on checkboxes and update the variable array accordingly with the right checkbox values.

I just needed 2 things:
- a way to fetch data on existing goals associated with a post, and to add ticks the respective checkboxes based on that fetched data
- a way to query (using querySelectorAll) the checked status of all the checkboxes on clicking Submit to update.


computed: {
checkedGoals() {
const ret = {}
for (let i = 0; i < this.selectGoals.length; i++) {
for (let j = 0; j < this.post.goals.length; j++) {
if (this.post.goals[j].id === this.selectGoals[i].id) {
ret[this.post.goals[j].id] = true
}
}
}
return ret
},
}

methods: {
listenChecked() {
const checkboxes = document.querySelectorAll(
'input[type=checkbox][name=selectedGoalInputs]'
)
let checkedArr = []
checkedArr = Array.from(checkboxes)
.filter((i) => i.checked)
.map((i) => i.value)
this.newGoals = checkedArr
}
}
// and then add this function to the updatePost function to use the this.newGoals data in the request body

Ref:
https://forum.vuejs.org/t/check-checkboxes-on-array-values/46631/2
https://stackoverflow.com/a/14544545

Day 76 - 50% code, 50% marketing https://golifelog.com/posts/50percent-code-50percent-marketing-1615973795579

From a perspective of maintaining cognitive slack for exploration and learning (or just sanity!), it really does make more sense to go with at least one-week blocks of 50/50 coding and marketing. I like to live and work in cycles and seasons, in a pulse and pause manner, so this idea resonates. Perhaps I can experiment with 2-3 week cycles too, to see which one best fits.

Can’t wait to get on this 50/50 schedule!

Completed misc paperwork for forms, checklists, price schedules etc for gov project bid

Finished design consultancy proposals for 2 MSF government projects

To bid for project on Gebiz next...

Indie making doesn't feed the fam yet, so gotta hustle in other ways, as much as I'm trying to transition out of consultancy!

Day 75 - Slack is good https://golifelog.com/posts/slack-is-good-1615880544602

Systems with slack are more resilient… The mistake happens when we over-index on the easily measured short-term wins and forget to account for the costs of system failure. ~ Seth Godin

Managed to get checkboxes working without using v-model

Ok so I managed to create a computed property to pre-check any goals that's already linked to the post. I can also send data about the checkboxes now without using v-model.

But not able to merge both of these functions yet - the pre-checked goals don't appear in the data that comes from a function listening to the @change of the checkboxes. Could have solved it today if not for the downtime...

😓😰😵 Fixed downtime due to crashed Strapi app

My backend Strapi app just crashed all of a sudden even though I didn't deploy anything the past few days. Turned out, some SSL settings code were outdated and didn't work with a new version of the postgres module that Heroku recently updated to.

(Mystery SOLVED: I didnt make any updates to my pg package. In my package.json it's still v7.x. The pg package that's causing the issue is v8.0. And the weird thing is this was raised in a Strapi Github issue was back in May 2020, and fixes been released since. So it's Heroku that's the main culprit. They deprecated some SSL endpoint recently, damnit!🤬)

Incidents like this where the app just crashes out of nowhere just gives me a heart attack! But thankfully @keenencharles and @yuyu were able to help walk through it with me and narrow down to the issue together.

Total downtime was ~4h, only found out after 1h+, and took 2h+ to fix.

Ref:
Answer: https://forum.strapi.io/t/error-no-pg-hba-conf-entry-for-host-ssl-off/3409/2

Code: https://strapi.io/documentation/developer-docs/latest/setup-deployment-guides/configurations.html#database

Other instances:
https://github.com/strapi/strapi/issues/5696
https://github.com/strapi/strapi/issues/5956
https://github.com/strapi/strapi/pull/6019
https://github.com/strapi/strapi/pull/6050

Heroku changelog:
11 Mar - SSL Endpoint Deprecation Schedule
https://devcenter.heroku.com/changelog-items/2080

23 Feb - All Heroku Postgres client connections require SSL
https://devcenter.heroku.com/changelog-items/2035

LifeBlog - Abstainers vs moderators https://golifelog.com/posts/abstainers-vs-moderators-1615791591619

When it comes to habits, are you an abstainer, or a moderator?

You’re an abstainer when you find it easier to follow a rule 100% of the time...You’re a moderator when you need to release the pressure a bit from time to time, in order to sustain the longer habit forming journey.

Makes me wonder, how can Lifelog be just as helpful for moderators as with abstainers? Introducing the Most Streaks leaderboard is one way. Moderators can feel free to break their streak, then bounce back again and again, accumulating a series of streaks which will count up in a number called Most Streaks. That way they don’t have to feel bad about breaking their current streak, and have their own way to track progress.

What else can we do to integrate moderators and abstainers here on Lifelog?
Jason Leow Author

@okitsjoe thanks for the ideas! Yeah users can see the no. of posts they wrote now, and soon can see the number of streaks they have (number of times they broke their streak and came back)

0 Likes
Joel Patrizio

I think a simple solution would be counting the total amount of entries, it's a number that will always go up when you are active. I've also seen in the app "Loop Habit Tracker" that you are presented with your own history of previous streaks, so it can be encouraging to try to beat your previous best streak.

0 Likes

Day 74 - Permissionless entrepreneurship...and life https://golifelog.com/posts/permissionless-entrepreneurshipand-life-1615791163351

"indie hacking = permissionless entrepreneurship"

Expanding on it, it’s not just permissionless entrepreneurship I’m after, but permissionless work, career, lifestyle. Everything.

Got inline editing of post title working!

Managed to integrate inline editing of the post title with the body text, so that it both gets updated on a single PUT request.

Now on to the hard part - inline editing of goals tags for each post... how to v-model on v-for list of goals, yet still v-bind to existing goals that's already associated with the post? 🤔

Day 73 - Create the gold rush to sell shovels https://golifelog.com/posts/create-the-gold-rush-to-sell-shovels-1615703171745

I’m always amazed that Michelin—a tire (or tyre) company—runs one of the most prestigious food review/ratings guide in the world, the Michelin Guide.. Food reviews might seem like a tangential offering to their main business – tires. But it makes sense complete sense if you think about it. To get more people driving and using cars, you attract them with travel and great food. And when they drive more, they need tire changes.

So basically, the principle seems to be this:

Make a product for your product. Make a side hustle for your main hustle. Create the fun fair and the popcorn for your main circus show. Create the gold rush and sell shovels......

Added inline editing/delete to posts

Did quick work of inline edit/del for posts, tahnks to existing code from edit/del of comments. To make the visual transition less jumpy/jarring when switching to edit mode (a textarea appears over the body text of the post), I set the textarea style height to reflect the scroll height of the text content in the textarea on click of the 'edit' btn.

editPostTextarea.style.height = 'auto'
editPostTextarea.style.height = `${editPostTextarea.scrollHeight}px`

Also added auto resize so that the textarea will extend vertically automagically as you type.

Also added `this.$root.$emit('fetchPosts')` upon delete so that the main feed on the home page will reload to reflect the absence of the deleted post

Tech debt: Edit or delete of post title, tagged goals not available yet. No auto edit/delete of related comments and notifs this time. I think I can let it pass till next round.