<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rish Pandey</title>
    <description>The latest articles on DEV Community by Rish Pandey (@rishpandey).</description>
    <link>https://dev.to/rishpandey</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F294831%2F0f18fae1-ee10-41d2-8ebb-c0dbea61c9b3.jpeg</url>
      <title>DEV Community: Rish Pandey</title>
      <link>https://dev.to/rishpandey</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rishpandey"/>
    <language>en</language>
    <item>
      <title>How to implement preference based notifications in laravel?</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Mon, 19 Apr 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/how-to-implement-preference-based-notifications-in-laravel-1ce</link>
      <guid>https://dev.to/rishpandey/how-to-implement-preference-based-notifications-in-laravel-1ce</guid>
      <description>&lt;p&gt;A few days back, I was asked to implement a pretty awesome notification system on one of my client's laravel application, we are calling it, &lt;strong&gt;Granular Preference for Notifications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So the user story goes,&lt;/p&gt;

&lt;p&gt;A user can select if they wish to receive a notification via email, broadcast, both or neither. We have a bunch of notifications like newletter, maintenance, invitations, messages etc. Some of these are important to some users, essential for others and outright annoying to some. So, this is a pretty useful and much needed feature.&lt;/p&gt;

&lt;h3&gt;
  
  
  How I approached this problem?
&lt;/h3&gt;

&lt;p&gt;There is actually an existing &lt;a href="https://github.com/williamcruzme/laravel-notification-settings"&gt;laravel package&lt;/a&gt; which does something similar and looks promising. I looked at the package and was going use it but instead wanted to have something custom-made for our specific use case.&lt;/p&gt;

&lt;p&gt;I figured what we need at most is some way to edit the &lt;code&gt;via()&lt;/code&gt; method to return the appropriate channels based on what user has set in their profile.&lt;/p&gt;

&lt;p&gt;The documentation shows something like this as well,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * Get the notification's delivery channels.
 *
 * @param mixed $notifiable
 * @return array
 */
public function via($notifiable)
{
    return $notifiable-&amp;gt;prefers_sms ? ['nexmo'] : ['mail', 'database'];
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How I solved this?
&lt;/h2&gt;

&lt;p&gt;I created a new abstract class classed &lt;code&gt;PreferenceBasedNotification&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Notifications;

abstract class PreferenceBasedNotification extends Notification{
    final public function via($notifiable){}
    abstract public function toMail($notifiable);
    abstract public function toBroadcast($notifiable);
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every notification where a user can set a preference will inherit this abstract class and will have to implement &lt;code&gt;toMail()&lt;/code&gt; and &lt;code&gt;toBroadcast()&lt;/code&gt; and can't implement &lt;code&gt;via()&lt;/code&gt; to fulfill the contract.&lt;/p&gt;

&lt;p&gt;Why &lt;code&gt;toMail()&lt;/code&gt; and &lt;code&gt;toBroadcast()&lt;/code&gt; are abstract? It is to make sure that if a user is opting for both mail and broadcast then the notification has to provide it. For &lt;code&gt;via()&lt;/code&gt; being final, I decided that individual notifications can not edit the logic to check user's channel preference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Setup
&lt;/h3&gt;

&lt;p&gt;I used two tables to achieve this, one keeps tracks of all the notifications where user can set a preference.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;preference_based_notifications&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| event_text | description | notification_class |
|-------------|-------------|------------------------|
| New Message | ... | NewMessageNotification |
| New Event | ... | NewEventNotification |

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;user_notification_preferences&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| notification_id | user_id | receive_email | receive_notification |
|-----------------|---------|---------------|----------------------|
| 1 | 1 | true | false |
| 2 | 1 | true | true |

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implementing the &lt;strong&gt;via()&lt;/strong&gt; method
&lt;/h3&gt;

&lt;p&gt;Now the only thing left to do is to implement &lt;code&gt;via()&lt;/code&gt;. This method has to check for user preference and based on that return appropriate channel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;final public function via($notifiable)
{
    $viaChannels = [];
    $preference = $this-&amp;gt;getPreference($notifiable-&amp;gt;user_id);

    if ($preference-&amp;gt;receive_email) {
        $viaChannels[] = 'mail';
    }
    if ($preference-&amp;gt;receive_notification) {
        $viaChannels[] = 'broadcast';
    }

    return $viaChannels;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can implement a method to check user's preference like this,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private function getPreference($userID)
{
    // get_class returns the class name with namespace
    // we need to get extract class name

    $currentClass = Arr::last(explode('\\', get_class($this)));

    $event = DB::table('notification_events')
        -&amp;gt;where('notification_class', $currentClass)-&amp;gt;first();

    if (!$event) {
        return null;
    }

    return DB::table('user_notification_preferences')
        -&amp;gt;where('user_id', $userID)
        -&amp;gt;where('notification_event_id', $event-&amp;gt;id)
        -&amp;gt;first();
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. We can now look into the user_notification_preferences table and send notifications based on the user's choice.&lt;/p&gt;

&lt;p&gt;You can checkout the gist &lt;a href="https://gist.github.com/rishpandey/2689c481cc9e3209223cbf2e47d17449"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to add approx read time on posts in Jigsaw?</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Tue, 12 Jan 2021 00:00:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/how-to-add-approx-read-time-on-posts-in-jigsaw-i38</link>
      <guid>https://dev.to/rishpandey/how-to-add-approx-read-time-on-posts-in-jigsaw-i38</guid>
      <description>&lt;p&gt;My current blog is developed using &lt;a href="https://jigsaw.tighten.co/"&gt;Jigsaw&lt;/a&gt; and their &lt;a href="https://github.com/tighten/jigsaw-blog-template"&gt;awesome template&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Jigsaw is a framework for rapidly building static sites using the same modern tooling that powers your web applications.&lt;/p&gt;

&lt;p&gt;I absolutely love the design and made little to no changes on it. One thing I very much needed is to show read time on each article. This is how I accomplished it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a new helper in &lt;code&gt;config.php&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'getReadTime' =&amp;gt; function ($page, $wpm = 150) {
        $content = strip_tags($page-&amp;gt;getContent());
        $word_count = str_word_count($content);
        return ceil($word_count / $wpm);
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use the helper in &lt;code&gt;post-preview-inline.blade.php&lt;/code&gt;. In blog template this file is used to give an inline preview of posts.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; &amp;lt;a
    href="{{ $post-&amp;gt;getUrl() }}"
    title="Read more - {{ $post-&amp;gt;title }}"
    class="uppercase font-semibold tracking-wide mb-2"
    &amp;gt;
    {{ $post-&amp;gt;getReadTime() }} Minutes Read 
&amp;lt;/a&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Don't see only what you want to see</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Tue, 14 Jul 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/don-t-see-only-what-you-want-to-see-586</link>
      <guid>https://dev.to/rishpandey/don-t-see-only-what-you-want-to-see-586</guid>
      <description>&lt;p&gt;People have strong opinions. Some people are more passionate than others in their values and beliefs, but everyone has them. Making rational decisions where the emotion is strong is hard, overlooking the facts that don’t agree with our values is very often the default mode.&lt;/p&gt;

&lt;p&gt;The scientific term for this behavior is &lt;a href="https://en.wikipedia.org/wiki/Confirmation_bias#:~:text=Confirmation%20bias%20is%20the%20tendency,evidence%2Dbased%20decision%2Dmaking."&gt;Confirmation Bias&lt;/a&gt;. A tendency to favor or look for information that supports one’s personal belief, a very common &lt;a href="https://www.verywellmind.com/what-is-a-cognitive-bias-2794963#:~:text=A%20cognitive%20bias%20is%20a,and%20judgments%20that%20they%20make."&gt;cognitive bias&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wMz2uNOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rishpandey.com/images/posts/confirmation-bias.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wMz2uNOu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rishpandey.com/images/posts/confirmation-bias.png" alt="Confirmation Bias"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Take the example of Ed. He is a person with low self-esteem.&lt;/p&gt;

&lt;p&gt;Any person who sends a text and doesn’t get a reply thinks the other party must be busy. In this situation, Ed thinks that the other person doesn’t like him and chose to not reply.&lt;/p&gt;

&lt;p&gt;He is biased towards thinking bad about himself and will believe the occurrence or a piece of information that supports his existing belief. For Ed, neglect is the obvious conclusion where ignorance seems apparent.&lt;/p&gt;

&lt;p&gt;The same behavior goes to show why eyewitnesses are considered unreliable. The Innocence Project researchers have reported that &lt;strong&gt;73% of the 239 convictions overturned through DNA testing were based on eyewitness testimony&lt;/strong&gt;, &lt;a href="https://www.scientificamerican.com/article/do-the-eyes-have-it/"&gt;source&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A neighbor who doesn’t care for dogs and thinks dogs are dangerous sees a vicious dog attack an innocent child. A bystander who loves dogs sees the dog defending itself against a menacing child. Neither eyewitness account is reliable due to confirmation bias.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So, what to do?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The first thing is to address that you may have confirmation bias where you have strong opinions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be careful and educate yourself when making your mind about things in those areas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go out into the world, discuss your thoughts with others. Surround yourself with a diverse group of people, and don’t be afraid to listen to dissenting views.Challenge yourself with disagreements and fruitful dialogs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The true sake of an argument is to educate everyone involved in it.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why do we have leap years?</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Wed, 17 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/why-do-we-have-leap-years-271p</link>
      <guid>https://dev.to/rishpandey/why-do-we-have-leap-years-271p</guid>
      <description>&lt;h2&gt;
  
  
  How to check if a year is a leap year?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;(year % 400 === 0 || (year % 4 === 0 &amp;amp;&amp;amp; year % 100 !== 0));&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it means?
&lt;/h2&gt;

&lt;p&gt;Every 4th year is a leap year, except it’s not every 100th year, except it is every 400th year.&lt;/p&gt;

&lt;h2&gt;
  
  
  But, why?
&lt;/h2&gt;

&lt;p&gt;Leap years exist because the Earth rotates about 365.242375 times a year. We have 365 days in a normal year and this leads to 0.242375 days extra. 29th Februrary exists to make up for this fraction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;So, every 4th year we add an extra day, which makes 366 days that year and 365.25 days on average. Now, we went over the actual figure by 0.007625 days, which is almost a day every 131 years.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So, every 100 years we need to skip the leap day and that means we have &lt;code&gt;(366 * 24) + (365 * 76)&lt;/code&gt; per 100 years or 365.24 days per year. We are still lacking 0.002375 days per year. The error is small, almost a day every 421 years. This is still not small enough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;So, every 400 years we add a leap day, which takes us to &lt;code&gt;(366 * 97) + (365 * 303)&lt;/code&gt; per 400 years or 365.2425 days per year.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the difference is too low and it will take 8000 years when the total difference leads to an error of single day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not go further?
&lt;/h2&gt;

&lt;p&gt;Due to several reasons like the tidal acceleration of sun and moon which slows the rotation of the earth. The actual rotation time of 365.242375 days will have changed by an amount which can not be accurately predicted. And this is accurate enough for most practical purposes.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Stick to your stack</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Fri, 12 Jun 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/stick-to-your-stack-5epa</link>
      <guid>https://dev.to/rishpandey/stick-to-your-stack-5epa</guid>
      <description>&lt;p&gt;In the book, the pragmatic programmer, there is a section where the author compares a programmer to a craftsman. The craftsman or artisan mindset is a great way of thinking about our work. An artisan stands by her choices and work just like we must. Every artisan needs her favorite tools to do their finest work, as we programmers need our favorite programming languages, our editors and our stack.&lt;/p&gt;

&lt;p&gt;But, we programmers are fickle creatures and our whole industry is always gawking at another next best thing which is supposed to solve every programmer itch. Every day, we have ten new frameworks (and not enough good libraries). This trend makes us question our own choices so much that if we don’t take up anything new in a few months, it feels like we are getting left behind.&lt;/p&gt;

&lt;p&gt;Don’t get me wrong, we need to stay on top of the current technology. But it’s pointless to try and catch up to every new popular thing. What’s more important is, using a stack that you know well, will not let you forgive yourself when you cut corners or make bad structure choices. By allowing us to try new things every time, we start to think that a project is more about learning and less about perfection. And, we let ourselves off the hook and not hold us accountable for the quality of the project.&lt;/p&gt;

&lt;p&gt;I know your usual stack may feel boring and stale, the new thing surely looks very fun. It’s good to have fun and learn. There’s always a small chance that a new technology is better for you and for the things you are making right now. But you should know the tradeoffs.&lt;/p&gt;

&lt;p&gt;Always staring at documentation for the new thing you are trying out of FOMO is just not productive.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tools</category>
    </item>
    <item>
      <title>Why should you refactor?</title>
      <dc:creator>Rish Pandey</dc:creator>
      <pubDate>Mon, 08 Jun 2020 19:22:00 +0000</pubDate>
      <link>https://dev.to/rishpandey/why-should-you-refactor-3c4c</link>
      <guid>https://dev.to/rishpandey/why-should-you-refactor-3c4c</guid>
      <description>&lt;p&gt;You have been working on this feature for a long time. When the client pitched this great new addition, you felt this would take a week. And here you are working on a Saturday and nothing feels right. You start to question everything about your career choices, the impostor syndrome kicks in.&lt;/p&gt;

&lt;p&gt;Maybe you are not as great as you think (many of us are not).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HL7wlh4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D2048%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HL7wlh4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1456406644174-8ddd4cd52a06%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D2048%26q%3D80" alt="Stressed out"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s not you, it’s Technical Debt
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Technical Debt is a metaphor, coined by Ward Cunningham, that frames how to think about dealing with this cruft, thinking of it like a financial debt. The extra effort that it takes to add new features is the interest paid on the debt.”&lt;/p&gt;

&lt;p&gt;Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most of our work as programmers is paved by the need of stakeholders. The client usually wants something at the last moment and the conversation ends with, “just get it done before Y (an unimaginable deadline) or we will start loosing money”.&lt;/p&gt;

&lt;p&gt;You need to opt for the “quick way”.&lt;/p&gt;

&lt;p&gt;This is the curse of our craft, we have to make compromises that we know will come back to bite us (or another one of us) in the ass. These compromises allow us to meet the client’s deadline and save them money for now. Congratulations, the code is a step closer to a maintenance nightmare now.&lt;/p&gt;

&lt;p&gt;You will surely be entertained when the next feature request comes in.&lt;/p&gt;

&lt;p&gt;A few years go by. You keep adding features, layer upon layers of new code. Everything built upon the same code base, inheriting every misused design pattern and reflecting all your bad design choices. You are at the mercy of technical debt, if the interest rate is low it slow you down by days or weeks. If the rate is high, maybe you can’t even implement the feature without a rewrite.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pay the Debt with Refactoring
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;“Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behavior.”&lt;/p&gt;

&lt;p&gt;Martin Fowler&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fear not Padavan, refactoring is the way we can repay this debt. Just like any other loan, we keep paying the debt via refactoring and get to keep our sanity.&lt;/p&gt;

&lt;p&gt;To get started just remember the boy scout’s rule. Leave your code better than you found it. Make small, incremental changes that leave the code in a better state than it was found.&lt;/p&gt;

&lt;p&gt;You should get started with this by,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Naming your variables and functions well.&lt;/li&gt;
&lt;li&gt;Extracting each step of logic into a function.&lt;/li&gt;
&lt;li&gt;Keeping it DRY and removing duplicate code.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cleancode</category>
      <category>refactoring</category>
      <category>technicaldebt</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
