<?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>Forem: Juned Aslam</title>
    <description>The latest articles on Forem by Juned Aslam (@ijunedaslam).</description>
    <link>https://forem.com/ijunedaslam</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%2F1106271%2F25a0f2ff-82a3-485b-a404-efd323b49c46.jpg</url>
      <title>Forem: Juned Aslam</title>
      <link>https://forem.com/ijunedaslam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ijunedaslam"/>
    <language>en</language>
    <item>
      <title>main concept of every HTTP request</title>
      <dc:creator>Juned Aslam</dc:creator>
      <pubDate>Thu, 22 Jun 2023 08:19:27 +0000</pubDate>
      <link>https://forem.com/ijunedaslam/main-concept-of-every-http-request-1ikh</link>
      <guid>https://forem.com/ijunedaslam/main-concept-of-every-http-request-1ikh</guid>
      <description>&lt;p&gt;Request&lt;br&gt;
A request, or an HTTP request, is an action that is sent to a server in order to get something, or to send some information. This includes the URL of the server, the headers and the body of the request.&lt;/p&gt;

&lt;p&gt;Most of what will be explained will be important for requesting some information, but can also be applied when sending information as well.&lt;/p&gt;

&lt;p&gt;Loading&lt;br&gt;
Displaying a loading information for your users is an important step of a request because we never know what could happen on the network, maybe the connection is slow, maybe the server is slowed down because of the numerous requests.&lt;/p&gt;

&lt;p&gt;Showing a loader, or a text indicating that the request is still being made is an additional step that can make your application look more professional and is more user friendly than thinking that everyone has a fast internet connection.&lt;/p&gt;

&lt;p&gt;You can simulate slowed down request from the Developer Console in your favorite browser such as Firefox or Google Chrome.&lt;/p&gt;

&lt;p&gt;Error&lt;br&gt;
Things happen in the network, and we can't control everything beside what is happening inside our code.&lt;/p&gt;

&lt;p&gt;The network might be shut down momentarily, or the user has activated airplane mode, or the server has been down for some time. We never know what kind of problem there might be, or when it can happen but we know that there might be some problem and we must account for that.&lt;/p&gt;

&lt;p&gt;It is a good practice to account for these thing in the code, especially in JavaScript since sending a request often involves using a Promise, and a promise might be in a rejected state.&lt;/p&gt;

&lt;p&gt;You can also simulate an offline connection in your browser from the Developer Console.&lt;/p&gt;

&lt;p&gt;Cancelable&lt;br&gt;
If you plan on giving your users data from a remote API, at least provide a way of canceling these requests.&lt;/p&gt;

&lt;p&gt;This is a good practice and an added user experience bit in any application since getting a huge payload from a remote server might be costy for users that are on data plans and having the choice is a good way of showing your users that you are considering everyone, even those that cannot afford much data transfer.&lt;/p&gt;

&lt;p&gt;Using JavaScript and the Web API Fetch, you can use a signal along with an Abort Controller in order to provide a way of canceling a request.&lt;/p&gt;

&lt;p&gt;Validation&lt;br&gt;
Finally, you have sent a request, everything goes according to plan and you receive a successful response. Or is it?&lt;/p&gt;

&lt;p&gt;How can you be sure that the server won't change its response in a day, or a week, or a year? Your application might work for a while, but if anyone decide to send an object with a property instead of an array as usual, you might get into trouble because you'll try to iterate over an object instead of an array which is not possible out-of-the-box in JavaScript.&lt;/p&gt;

&lt;p&gt;Data validation is an important step, and might as well be mandatory in some case because even if you know what you are doing today and you are the only developer for a frontend &amp;amp; backend application, you might not be alone in a year and people might join the fight and help you.&lt;/p&gt;

&lt;p&gt;If you go back from a long vacation and the API has change, at least with data validation you know that this is a case you accounted for and your application won't crash suddenly (and you might even get better errors that will lead you to resolve this error quicker than without data validation).&lt;/p&gt;

&lt;p&gt;Also, with data validation, you can rely on languages that are strongly typed like TypeScript to ensure that once this data has been parsed and validated, you are 100% sure you can iterate over it instead of being afraid it might change in a near future.&lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
Here is what a beginner application might look like in React for the example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from "react";

export const App = () =&amp;gt; {
  const [users, setUsers] = useState([]);

  useEffect(() =&amp;gt; {
    fetch("https://jsonplaceholder.typicode.com/users").then(response =&amp;gt; {
      return response.json();
    }).then(newUsers =&amp;gt; {
      setUsers(newUsers);
    });
  }, []);

  return (
    &amp;lt;ul&amp;gt;
      {users.map(user =&amp;gt; (
        &amp;lt;li key={user.id}&amp;gt;{user.username}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, no loading state, no cancelable request, no accounting for errors nor data validation.&lt;/p&gt;

&lt;p&gt;Here is what it might look like with all these things added.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { Fragment, useEffect, useState, useCallback } from "react";

`const isValidUser = input =&amp;gt; {
  return typeof input === "object"
    &amp;amp;&amp;amp; input !== null
    &amp;amp;&amp;amp; typeof input.id === "number"
    &amp;amp;&amp;amp; typeof input.username === "string";
}

const isValidUsers = users =&amp;gt; {
  if (!Array.isArray(users)) {
    return false;
  }

  if (!users.every(user =&amp;gt; isValidUser(user))) {
    return false;
  }

  return true;
}

export const App = () =&amp;gt; {
  const [users, setUsers] = useState([]);
  const [abortController, setAbortController] = useState(new AbortController());
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);

  const cancel = useCallback(() =&amp;gt; {
    abortController.abort();
  }, [abortController]);

  useEffect(() =&amp;gt; {
    const newAbortController = new AbortController();
    const { signal } = newAbortController;

    setAbortController(newAbortController);
    setError(null);
    setLoading(true);

    fetch("https://jsonplaceholder.typicode.com/users", {
      signal
    }).then(response =&amp;gt; {
      if (response.ok) {
        return response.json();
      }

      return Promise.reject(new Error("Something went wrong"));
    }).then(newUsers =&amp;gt; {
      if (!isValidUsers(newUsers)) {
        throw new Error("Wrong response from the server");
      }

      setUsers(newUsers);
    }).catch(error =&amp;gt; {
      setError(error);
    }).finally(() =&amp;gt; {
      setLoading(false);
    });
  }, []);

  return (
    &amp;lt;Fragment&amp;gt;
      {loading &amp;amp;&amp;amp; (
        &amp;lt;small&amp;gt;Loading, please wait...&amp;lt;/small&amp;gt;
      )}
      {error &amp;amp;&amp;amp; (
        &amp;lt;small&amp;gt;{error.message}&amp;lt;/small&amp;gt;
      )}
      &amp;lt;button onClick={cancel}&amp;gt;Cancel&amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {users.map(user =&amp;gt; (
          &amp;lt;li key={user.id}&amp;gt;{user.username}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/Fragment&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course no styling has been applied so it looks awful but at least you get the idea.&lt;/p&gt;

&lt;p&gt;We added a way of canceling the request, a loading indication to reassure the user, a display of any error and a basic data validation mechanism in order to ensure the data we get is not corrupted or has been changed.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
We saw that in order to build reliable applications, there were 5 steps that we must follow whenever we make a request to a server:&lt;/p&gt;

&lt;p&gt;Send a proper request&lt;br&gt;
Display a loading state&lt;br&gt;
Display errors if any&lt;br&gt;
Make the request cancelable&lt;br&gt;
Validate the data we receive&lt;br&gt;
If you manage to follow these steps, you'll build highly reliable applications that are time-tested and sturdy.&lt;/p&gt;

&lt;p&gt;This will instantly make your application way better in the eyes of your users.&lt;/p&gt;

&lt;p&gt;These concepts are not tied to JavaScript nor React and can be applied to pretty much any language or any framework &amp;amp; library out there as long as you follow these steps.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Share Preferances right way</title>
      <dc:creator>Juned Aslam</dc:creator>
      <pubDate>Thu, 22 Jun 2023 08:03:51 +0000</pubDate>
      <link>https://forem.com/ijunedaslam/you-were-using-sharedpreferences-the-wrong-way-2nmd</link>
      <guid>https://forem.com/ijunedaslam/you-were-using-sharedpreferences-the-wrong-way-2nmd</guid>
      <description>&lt;p&gt;Let's keep it easy and simple&lt;/p&gt;

&lt;p&gt;Shared preferences&lt;br&gt;
Shared preferences allow you to store small amounts of primitive data as key/value pairs in a file on the device&lt;/p&gt;

&lt;p&gt;keep track of small bits of important&lt;br&gt;
Store information without needing a storage permission&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MainActivity extends AppCompatActivity {
    TextView sharedPref;
    Button buttonAdd;
    int count=0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SharedPreferences sp = getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
        count = sp.getInt("your_int_key", -1);


        sharedPref=findViewById(R.id.sharedPref);
        buttonAdd=findViewById(R.id.buttonAdd);
        sharedPref.setText(""+count);

        buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                sharedPref.setText(""+count);

                SharedPreferences sp = getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
                SharedPreferences.Editor editor = sp.edit();
                editor.putInt("your_int_key", count);
                editor.commit();
            }
        });

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

&lt;/div&gt;



&lt;p&gt;Lets Upgrade to PreferenceUtil&lt;br&gt;
you must be thinking why PreferenceUtil 🤔 , let's see why should we use this.&lt;br&gt;
1) Much cleaner and readable code.&lt;br&gt;
2) Can access any variable from any class.&lt;/p&gt;

&lt;p&gt;--&amp;gt; To get the value&lt;br&gt;
PreferenceUtil.getInstance(MainActivity.this).getCountNum();&lt;br&gt;
--&amp;gt; To set the value&lt;/p&gt;

&lt;p&gt;PreferenceUtil.getInstance(MainActivity.this).SetCountNum(count);&lt;br&gt;
3) Code is reduced.&lt;br&gt;
4) Variables using shared preferences are in one place.&lt;br&gt;
5) Fewer errors due to key naming.&lt;br&gt;
6) Easy to use with ViewModel.&lt;br&gt;
7) Very good for you to handle large projects.&lt;/p&gt;

&lt;p&gt;I hope these advantages are good enough for you to migrate😎.&lt;/p&gt;

&lt;p&gt;MainActivity Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.androxus.prefranceutil;

import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;


import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    TextView sharedPref;
    Button buttonAdd;
    int count=0;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        sharedPref=findViewById(R.id.sharedPref);
        buttonAdd=findViewById(R.id.buttonAdd);


//        SharedPreferences sp = getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
//        count = sp.getInt("your_int_key", -1);
        count=PreferenceUtil.getInstance(MainActivity.this).getCountNum();


        sharedPref.setText(""+count);
        buttonAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                sharedPref.setText(""+count);
                PreferenceUtil.getInstance(MainActivity.this).SetCountNum(count);


//                SharedPreferences sp = getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
//                SharedPreferences.Editor editor = sp.edit();
//                editor.putInt("your_int_key", count);
//                editor.commit();
            }
        });

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

&lt;/div&gt;



&lt;p&gt;PreferenceUtil class code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package com.androxus.prefranceutil;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

public class PreferenceUtil {


    public static final String COUNT_VALUE = "count_value";
    public static final String COUNT_NUM = "count";
    private static com.androxus.prefranceutil.PreferenceUtil sInstance;
    private SharedPreferences mPref;
    private SharedPreferences.Editor mEditor;

    private PreferenceUtil(final Context context) {
        mPref = PreferenceManager.getDefaultSharedPreferences(context);
    }
    public static com.androxus.prefranceutil.PreferenceUtil getInstance(final Context context) {
        if (sInstance == null)
            sInstance = new com.androxus.prefranceutil.PreferenceUtil(context.getApplicationContext());
        return sInstance;
    }

    public final int getCountNum() {
        return mPref.getInt(COUNT_NUM,0);
    }

    public final int getCount() {
        return mPref.getInt(COUNT_VALUE,0);
    }

    public void setCount(int count) {
        final SharedPreferences.Editor editor = mPref.edit();
        editor.putInt(COUNT_VALUE, count);
        editor.apply();
    }

    public void SetCountNum(int count) {
        final SharedPreferences.Editor editor = mPref.edit();
        editor.putInt(COUNT_NUM, count);
        editor.apply();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ENJOY HOPE YOU LIKE&lt;/p&gt;

</description>
      <category>android</category>
    </item>
  </channel>
</rss>
