Category: Web Programming

  • #02 – Core Concepts – Learn GraphQL

    In this post, we have discussed the core GraphQL concepts e.g. schema, types, queries, mutations, and subscriptions with example codes.

    Core Concepts of GraphQL

    • Schema
    • Types
    • Queries
    • Mutations
    • Subscriptions
    • Resolvers

    Scheme

    • The schema defines how a client can read and manipulate (add, update, and delete) data
    • It represents a contract between client and server
    • It consists of GraphQL types and the special root types
    • Root types define the entry points for the API (type Query, type Mutation, type Subscription)

    Types

    • GraphQL provides schema definition language (SDL) to define simple types
    • Types define the structure of the data and how the data is manipulated
    • GraphQL allows creating relationships between types

    Example Code

    //User type
    type User{
       id: ID!
       name: String!
       courses: [Course!]!
    }
    //Course type
    type Course{
       id: ID!
       title: String!
       url: String
       author: User!
    }
    // ! indicates that the field is required
    // One to many relationship is defined between User and Course //types

    Queries

    • Queries are used to fetch (read) data from GraphQL API
    • A query specifically describes what data it needs in the response
    • Arguments are passed in the queries to return/alter data based on the arguments
    • Queries can be used to get nested or relational data as well

    Example Code

    type Query{
       getCourses(last: Int): [Course!]!
    }
    //get all courses with only title field
    {
       courses: {
          title
       }
    }
    //get all courses with author info i.e. name
    {
       courses: {
          title
          author: {
             name
          }
       }
    }

    Mutations

    • Mutations are used to modify data i.e. create, update or delete
    • Mutations accept arguments (input) and payload (expected output)

    Example Code

    type Mutation {
        addUser(name: String!): User
    !
    }
    mutation {
       addUser (name: "junaid", courses: []) {
          id
          name
       }
    }

    Subscriptions

    • GraphQL subscriptions provide real-time updates to the subscribers
    • Whenever new data is added, the subscriptions notified or pushes the data back to the subscriber in real-time
    type Subscription{
       addUser: User!
    }
    subscription {
      newUser{
        id
        name
      }
    }

    Resolvers

    • For each query and mutation, there is a resolver function with the same name as the query or mutation
    • The resolver function communicates with the appropriate data source and sends the response
    //import Course from "../../models/Course"; mongoose model
    Query: {
        async allCourses() {
          try {
            const courses = await Course.find();
            return courses;
          } catch (err) {
            throw new Error(err);
          }
        }
    },
    Mutation: {
        async addCourse(parent, { name, url }, context, info) {
          try {
            const course = await new Course({name, url});
            return course.save();
          } catch (err) {
            throw new Error(err);
          }
        }
    }
  • #01 – Introduction – Learn GraphQL

    In this post, we have discussed what is GraphQL, the differences between REST API’s and GraphQL API development architectures, and an example scenario to elaborate on the differences between the two approaches.

    What is GraphQL?

    • It is a new API development standard
    • It is a query language for API’s
    • It provides declarative syntax to fetch data from multiple data sources
    • It’s an alternate to REST API development architecture
    • Unlike REST, it exposes only a single endpoint to respond to queries
    • It solves the problem of over-fetching and under-fetching the data
    • It speeds up the development because we don’t need to adjust API every time the front-end app data requirements are adjusted

    What are the differences between REST and GraphQL architectures?

    • A REST endpoint provides all the data (fields) returned by the endpoint whereas the GraphQL endpoint only provides the requested data (fields) thus improving the performance
    • In the case of REST, multiple requests are made to fetch data from different REST endpoints whereas the GraphQL endpoint can combine and return data from multiple queries in a single request

    Example Scenario:

    Let’s say you have a front-end application page where you want to display the author’s name with 3 posts of that author and 3 comments on each post. If we have a REST API we will call 3 endpoints to implement this feature:

    1. Call /users/<id> endpoint to fetch the user (author) information
    2. Call /users/<id>/posts endpoint to fetch all posts by the user (author)
    3. Call /posts/<id>/comments endpoint to fetch all comments on each post

    As you can see that we need to call 3 endpoints separately to get all the required data. Moreover, we are fetching all user posts and all post comments whereas we only need to display 3 posts and 3 comments on each post.

    GraphQL simplifies this process and provides a more efficient way to handle these kind of scenarios. The above data can be received from single query to GraphQL API as follows:

    {
       user(id: "123"){
          name,
          posts(id: "12344...", last: 3){
             title,
             description,
             comments(id: "453355...", last: 3){
                text,
                author
             }
          }
       }
    }

    In the next post, we will learn about the core concepts of the GraphQL.

  • #02 – Data Fetching – Learn Next.js

    Next.js provides three functions to fetch data for pre-rendered pages:

    getStaticProps():

    1. Used for static generation (pre-rendering technique)
    2. Fetches data at build-time
    3. When an async function getStaticProps() is called from the page component, the next.js will pre-render this page at build time using the props returned by that function (see Examples)
    4. The context parameter used as an argument of getStaticProps() function is an object containing following parameters (see details here):
      1. params
      2. preview
      3. previewData
      4. locale
      5. locals
      6. defaultLocale
    5. getStaticProps() function returns an object with following parameters (see details here):
      1. props (required)
      2. revalidate
      3. notFound
      4. redirect
    6. Imports used inside the getStaticProps() function are not bundled for the client side
    7. Server side code can be written inside the getStaticProps() function e.g. to read files on the server or to communicate with the database
    8. API routes defined inside the next.js app should not be called inside getStaticProps() function using fetch() instead import the API route and call its function
    9. Incremental Static Regeneration
      1. Used to update the statically served page in the background after some interval defined as revalidate parameter
    10. Query parameters are not available inside the getStaticProps() function because it runs on the build-time instead of request-time
    11. Server-side code (e.g. database queries) can be written securely inside this function because this function only runs on the server side and is not included in client-side bundle
    12. This function saves the returned data inside a JSON file along with the HTML file which can then be used for future page requests using next/link or next/router
    13. This means that in client-side page transitions, the getStaticProps() function is not called instead the data saved in the JSON file is passed to the component
    14. getStaticProps() function can only be exported from pages
    15. In development (npm run dev), getStaticProps() function is called on every request

    Example (JavaScript):

    //https://nextjs.org/docs/basic-features/data-fetching
    // posts will be populated at build time by getStaticProps()
    function Blog({ posts }) {
      return (
        <ul>
          {posts.map((post) => (
            <li>{post.title}</li>
          ))}
        </ul>
      )
    }
    
    // This function gets called at build time on server-side.
    // It won't be called on client-side, so you can even do
    // direct database queries. See the "Technical details" section.
    export async function getStaticProps(context) {
      // Call an external API endpoint to get posts.
      // You can use any data fetching library
      const res = await fetch('https://.../posts')
      const posts = await res.json()
    
      // By returning { props: posts }, the Blog component
      // will receive `posts` as a prop at build time
      return {
        props: {
          posts,
        },
        // Next.js will attempt to re-generate the page:
        // - When a request comes in
        // - At most once every second
        revalidate: 1, // In seconds
      }
    }
    
    export default Blog

    Example (TypeScript):

    import { InferGetStaticPropsType } from 'next'
    
    type Post = {
      author: string
      content: string
    }
    
    export const getStaticProps = async (context) => {
      const res = await fetch('https://.../posts')
      const posts: Post[] = await res.json()
    
      return {
        props: {
          posts,
        },
        // Next.js will attempt to re-generate the page:
        // - When a request comes in
        // - At most once every second
        revalidate: 1, // In seconds
      }
    }
    
    function Blog({ posts }: InferGetStaticPropsType<typeof getStaticProps>) {
      // will resolve posts to type Post[]
    }
    
    export default Blog

    getStaticPaths():

    • Used for pre-rendering of paths (or dynamic routes e.g. /pages/posts/[id].js) at build-time
    • This function need to return paths object (required)
    • The paths returned using paths object are pre-rendered at build-time
    • Fallback key is also required and can have either true or false values
    • fallback: false means that the pages other than the returned from paths object will show 404
    • fallback: false is useful if there are small number of pages to be statically generated otherwise the build time will be increased
    • fallback: true can be used if you want to pre-render some pages at build-time then load the other pages when they are requested using the Fallback pages (see example – fallback: true)

    fallback: true is useful if your app has a very large number of static pages that depend on data (think: a very large e-commerce site). You want to pre-render all product pages, but then your builds would take forever.

    Instead, you may statically generate a small subset of pages and use fallback: true for the rest. When someone requests a page that’s not generated yet, the user will see the page with a loading indicator. Shortly after, getStaticProps finishes and the page will be rendered with the requested data. From now on, everyone who requests the same page will get the statically pre-rendered page.

    This ensures that users always have a fast experience while preserving fast builds and the benefits of Static Generation.

    fallback: true will not update generated pages, for that take a look at Incremental Static Regeneration.

    https://nextjs.org/docs/basic-features/data-fetching#when-is-fallback-true-useful

    Example (fallback: false):

    // pages/posts/[id].js
    
    function Post({ post }) {
      // Render post...
    }
    
    // This function gets called at build time
    export async function getStaticPaths() {
      // Call an external API endpoint to get posts
      const res = await fetch('https://.../posts')
      const posts = await res.json()
    
      // Get the paths we want to pre-render based on posts
      const paths = posts.map((post) => ({
        params: { id: post.id },
      }))
    
      // We'll pre-render only these paths at build time.
      // { fallback: false } means other routes should 404.
      return { paths, fallback: false }
    }
    
    // This also gets called at build time
    export async function getStaticProps({ params }) {
      // params contains the post `id`.
      // If the route is like /posts/1, then params.id is 1
      const res = await fetch(`https://.../posts/${params.id}`)
      const post = await res.json()
    
      // Pass post data to the page via props
      return { props: { post } }
    }
    
    export default Post

    Example (fallback: true):

    // pages/posts/[id].js
    import { useRouter } from 'next/router'
    
    function Post({ post }) {
      const router = useRouter()
    
      // If the page is not yet generated, this will be displayed
      // initially until getStaticProps() finishes running
      if (router.isFallback) {
        return <div>Loading...</div>
      }
    
      // Render post...
    }
    
    // This function gets called at build time
    export async function getStaticPaths() {
      return {
        // Only `/posts/1` and `/posts/2` are generated at build time
        paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
        // Enable statically generating additional pages
        // For example: `/posts/3`
        fallback: true,
      }
    }
    
    // This also gets called at build time
    export async function getStaticProps({ params }) {
      // params contains the post `id`.
      // If the route is like /posts/1, then params.id is 1
      const res = await fetch(`https://.../posts/${params.id}`)
      const post = await res.json()
    
      // Pass post data to the page via props
      return {
        props: { post },
        // Re-generate the post at most once per second
        // if a request comes in
        revalidate: 1,
      }
    }
    
    export default Post

    getServerSideProps():

  • #01 Introduction – Learn Next.js

    What is Next.js?

    Next.js is a framework used to develop production ready React applications. Next.js provides many useful features e.g. pre-rendering, smart bundling, dynamic file-based routing, route pre-fetching and many more. In this blog post, we have discussed the prerequisites, how to create next.js application, next.js pages, and pre-rendering techniques.

    Prerequisites:

    Create New Application:

    • Open Command Prompt, CD into the folder where you want to create the application
    • Run the command:
    npx create-next-app
    • CD into the app folder
    • Run the command npm run dev to start the app in development mode
    • Run the command npm run build to generate the optimized build which can be used for production purposes
    • Run the command npm run start to start the production server

    Pages in Next.js:

    • In next.js, pages are React components and are available inside the pages folder
    • The names of the component files become the URL of the page
    • For example /pages/about.js component is accessible via /about URL
    • Dynamic routes can be implemented by creating dynamic files e.g. /pages/posts/[id].js which expose the URL like /posts/1, /posts/2 etc.

    Pre-rendering:

    In next.js, pages are pre-rendered before they are displayed in the browser which improves the performance and SEO of the web pages. Next.js let you choose the pre-rendering technique for each page. Next.js support two type of pre-rendering:

    • Static Generation
      • Recommended by Next.js
      • HTML of the page is generated once at build time and is reused on each request
      • Improved performance due to the CDN caching with no extra configuration
      • A page can be generated statically with or without data
      • Static Generation without Data
        • This is the default pre-rendering technique
        • These pages do not require to fetch any data from external sources
        • HTML page is generated at build time when we run npm run build
      • Static Generation with Data
        • These pages require to fetch data from external sources e.g. an API
        • If page contents are fetched from external source, then use getStaticProps() function
        • If page paths are fetched from external source, e.g. in case of dynamic routing, then use getStaticPaths() function
        • Some pages may require both features so both functions can also be used on that page
        • These functions gets called at build time and populate the dynamic content from external sources
      • Static generation is always recommended in the cases when the page can be pre-rendered ahead of a user’s request
      • Static generation is not recommended in the cases when the page data is frequently updated or if page content is updated on every request
        • In that case either use static generation with client-side rendering where some parts can be pre-rendered and the others on client-side
        • OR use server side rendering where all content of the page is populated on each request
    • Server side Rendering
      • The HTML of the page is generated on each request
      • To use server side rendering export async function getServerSideProps() from the bottom of the page
      • This function is called by the server on each request

    Client-side rendering is also supported in next.js where some parts of the pages can be rendered by the client side JavaScript.

    References:

    https://nextjs.org/docs/

  • Ep. 001: What is HTML? Learn HTML & HTML5

    This post belongs to the HTML course titled “Learn HTML & HTML5”. In this post, we have discussed what is HTML?

    • HTML stands for Hyper Text Markup Language
    • It’s not a programming language
    • HTML is used to define markup/contents of a web page
    • HTML provides tags for different type of contents e.g. link (<link>), paragraph (<p>), image (<img>), video (<video>) etc.
    What is HTML?

    All websites are built using HTML tags, so HTML is the most important language to learn.

    If you have any questions, please let us know in the comments section. Thanks

  • NPM Commands Not Working in Integrated Terminal of VSCode

    Visual Studio Code (VSCode) provides an integrated terminal to run commands inside the current directory. Recently, I installed VSCode and tried to run the NPM commands and it shows following errors:

    internal/modules/cjs/loader.js:968
      throw err;
      ^
    
    Error: Cannot find module 'C:\Program Files\nodejs\node_modules\npm\bin\node_modules\npm\bin\npm-cli.js'
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
        at Function.Module._load (internal/modules/cjs/loader.js:841:27)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
        at internal/main/run_main_module.js:17:47 {
      code: 'MODULE_NOT_FOUND',
      requireStack: []
    }
    internal/modules/cjs/loader.js:968
      throw err;
      ^
    
    Error: Cannot find module 'C:\Program Files\nodejs\node_modules\npm\bin\node_modules\npm\bin\npm-cli.js'
        at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)
        at Function.Module._load (internal/modules/cjs/loader.js:841:27)
        at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
        at internal/main/run_main_module.js:17:47 {
      code: 'MODULE_NOT_FOUND',
      requireStack: []
    }

    Reasons:

    This error could be due to the following reasons:

    1. The Node/NPM path is not added in the Environment Variable PATH (for Windows)
    2. You are not running VSCode as an administrator

    Solutions:

    1. To add Node path to the Environment Variable PATH, follow the instructions here
    2. Change the default shell of Integrated Terminal to Command Prompt.
    3. Close VSCode and open VSCode as an administrator
    4. To automatically run VSCode as an administrator, follow the instructions listed here

    I hope it will help to resolve these errors. 🙂

  • Common PHP Warnings/ Errors and their Solutions

    Recently, we have updated our PHP version to the latest stable version (7.4.9) for our WordPress website. After the update we started getting PHP warnings. We have listed some of the warnings with their possible solutions in this blog post.

    E_WARNING:

    count(): Parameter must be an array or an object that implements Countable

    Solution:

    // replace this kind of code:
    if (count($array_name) > 0)
    // with
    if (is_countable($array_name) && count($array_name) > 0)

    E_WARNING:

    Invalid argument supplied for foreach()

    Solution:

    // replace following kid of code:
    foreach ($array_name as $item) {
     // ...
    }
    // with
    foreach ((array) $array_name as $item) {
     // ...
    }

    References:

    • https://stackoverflow.com/questions/2630013/invalid-argument-supplied-for-foreach
    • https://wordpress.org/support/topic/count-parameter-must-be-an-array-or-an-object-that-implements-countable-6/

  • Get Started with Redux in React Application

    npm install --save react-redux @reduxjs/toolkit

    Create a file src/store/index.js and add following code in it:

    import { configureStore } from '@reduxjs/toolkit';
    import { combineReducers } from 'redux';
    const reducer = combineReducers({
      // here we will be adding reducers
    })
    const store = configureStore({
      reducer,
    })
    export default store;

    To link our app with the redux store update the main app file as follows:

    ...
    ...
    import { Provider } from 'react-redux';
    import store from './store';
    
    ReactDOM.render(
      <Provider store={store}>
          <App />
        </Provider>
    ,
      document.getElementById('root')
    );
  • Angular Concepts

    In this blog post, we have discussed some JavaScript and Angular concepts.

    What is the difference between synchronous and asynchronous approach in programming?

    In synchronous approach, the next statement will not be executed until the completion of the previous statement. Whereas, in asynchronous approach, the next statement will not wait for the completion of the previous statement.

    What is observable?

    An observable is a declarative function which can be subscribed to take actions on the received results. The observables are/can be:

    • Declarative i.e. they are executed only when they are subscribed
    • Unsubscribed as well
    • Used for asynchronous processing of statements
    • Angular uses RxJS library for observables

    What is a Promise in JavaScript?

    A promise object can return values in an asynchronous way. A promise maybe in 1 of the 3 states: fulfilled, rejected or pending. Promises are executed at the same time when they are created.

    What is the Difference between Observable and Promise?

    • Observable is declarative which means it’s executed only when subscribed whereas the promise is imperative which is executed as soon as it’s created.
    • Observables provide many values whereas the promises provide single value.
    • Observables are cancellable whereas the promises are not.

    What is ForkJoins?

    Forkjoin is used to execute multiple promises (e.g. http requests) in parallel and returns a single array containing the response from each observable.

    References:

  • How to Optimize an Angular Application?

    In this blog post, we have listed some of the techniques which can be used to first measure the performance of an angular application and then optimize the speed, loading time and performance of an angular application.

    How to Measure the Performance of an Angular Application?

    To measure the performance of an angular application, generate a production build of the app using following command in the root directory of Angular CLI project:

    ng build --prod --source-map

    We can use an npm package source-map-explorer to analyze and generate a report of the performance of the angular application. To get started, install the npm package using the following command:

    npm install source-map-explorer

    Now add following line inside the scripts section of the package.json file:

    "bundle:report": "source-map-explorer dist/demo-app/**/*.js"

    Please change the project name i.e. ‘demo-app’ to the name of your project.

    Now we can run the following command to generate the performance report of the app:

    npm run bundle:report

    Following are some of the techniques to optimize the speed, loading time and performance of an angular application:

    1. Lazy Loading

    Lazy loading means loading the resources, required for the component, only when that particular component is requested to load. It improves the performance of the angular application. In an angular application, lazy loading is implemented by dividing the application into modules.

    Resources:

    2. Preloading

    Preloading helps to improves the performance of the angular application by preloading the resources in cache required for faster future navigation.

    Resources:

    3. Web Workers

    Web workers are used to offload certain heavy functionality from the main application thread thus improving the performance of the angular application.

    4. Optimization of Template Expressions

    Try not to use high computation functions/methods inside the template expressions to improve the performance of the angular application.

    5. Optimize the Use the NgZone/Zone for Change Detection

    ngzone/zone library is used to detect the changes and then reloading the component’s view with updated data. To avoid updating the reloading of the view on each small change runOutsideAngular method of ngzone can be used to improve the performance of the application.

  • Angular Application is not working in IE11?

    If your angular application is not working in IE11, then the following simple steps can be used to make it work.

    1. Install the following packages using npm
      1. npm install –save classlist.js
      2. npm install –save web-animations-js
    2. Go into polyfills.ts file and uncomment the following lines
      1. import ‘classlist.js’;
      2. import ‘web-animations-js’;
    3. Go into tsconfig.ts file and change the ‘target’ attribute to ‘es5’
    4. Go into index.html file and add the following meta tag in the head tag
      1. <meta http-equiv=”X-UA-Compatible” content=”IE=edge” />

    That’s all, I hope it will help.

  • Server Side Pagination Using NodeJS, MongoDB and Angular Material Tables

    Normally, we use Angular Material’s data tables with pagination (mat-paginator) to list the results. This is not an efficient and optimal approach particularly if there are lots of records to show in the table. Angular Material’s pagination just divides the received records into the paginated records. So, if we need to display lots of records in data tables, then the efficient and optimal approach is to use Server Side Pagination. Following, sections will demonstrate the server-side pagination using NodeJS (API), MongoDB (database), and Angular Material data tables.

    API using NodeJS and MongoDB

    Following is a sample code, written in NodeJS with MongoDB model which query records from a MongoDB collection based on the current page (page), number of records per page (pageSize), and page type (pageType) (first, last, page). Depending on the type of page, MongoDB query is prepared which then returns the total records (count) matching the query, paginated records (depending on pageSize) (data), and the current page (currentPage).

    router.post('/paginated/', (req, res) => {
        // get page from query params or default to first page
        const page = parseInt(req.query.page) || 1;
        const pageType = req.query.pageType || 'first';
        const pageSize = parseInt(req.query.pageSize) || 5;
        if(pageType == 'first'){
            PermissionUsage.countDocuments({}).exec(function(err, count) {
                if (err) return res.status(500).json({success: false, message: err.message});
                PermissionUsage.find({}).limit(pageSize).exec(function(err, permissionUsages) {
                    if (err) return res.status(500).json({success: false, message: err.message});
                    res.status(200).send(JSON.stringify({success: true, data: permissionUsages, pager: {total: count, currentPage: page}}));
                });
            });
        }else if(pageType == 'page'){
            PermissionUsage.countDocuments({}).exec(function(err, count) {
                if (err) return res.status(500).json({success: false, message: err.message});
                PermissionUsage.find({}).skip((page-1)*pageSize).limit(pageSize).exec(function(err, permissionUsages) {
                    if (err) return res.status(500).json({success: false, message: err.message});
                    res.status(200).send(JSON.stringify({success: true, data: permissionUsages, pager: {total: count, currentPage: page}}));
                });
            });
        }else{
            PermissionUsage.countDocuments({}).exec(function(err, count) {
                if (err) return res.status(500).json({success: false, message: err.message});
                PermissionUsage.find({}).skip((page-1)*pageSize).limit(pageSize).exec(function(err, permissionUsages) {
                    if (err) return res.status(500).json({success: false, message: err.message});
                    res.status(200).send(JSON.stringify({success: true, data: permissionUsages, pager: {total: count, currentPage: page}}));
                });
            });
        }
    });
    

    Requesting Paginated Data From Angular Application

    myService.service.ts

    getPaginatedPermissionUsage(page, pageType, pageSize){
        return this.http.get('http://localhost:3000/permission-usages/paginated/?page='+page+'&pageType='+pageType+'&pageSize='+pageSize);
      }

    In a service we have created a method which calls our API’s endpoint to receive the paginated records. Here page parameter represents the current page, pageType represents whether the page is first, last or normal page and pageSize represents the number of records per page.

    myComponent.component.ts

    pager:any = {currentPage: 1, total: 0};
    page: number = 1;
    pageType: string = 'first';
    totalPages: number = 1;
    pageSize: number = 5;
    ....
    ....
    ....
    getPaginatedResults(pageNumber = 1){
    this.page = pageNumber;
    if(this.page == 1){
          this.pageType = 'first';
    }else if(this.page == window.Math.ceil(this.pager.total/this.pageSize)){
          this.pageType = 'last';
    }else{
          this.pageType = 'page';
    }
    this.myService.getPaginatedPermissionUsage(this.page, this.pageType, this.pageSize).subscribe((res:any) => {
          this.pager = res.pager;
          this.totalPages = window.Math.ceil(this.pager.total/this.pageSize);
          this.dataSource.data = res.data;
    });
    }

    myComponent.component.html

    <ul *ngIf="pager.total && pager.total > pageSize" class="pagination">
            <li class="page-item first-item">
                <a routerLink="/reports" [queryParams]="{ page: 1 }" [ngClass]="{disabled:pager.currentPage == 1}" *ngIf="pager.currentPage != 1" (click)="getPaginatedResults(1)" class="page-link">First</a>
            </li>
            <li class="page-item previous-item">
                <a routerLink="/reports" [queryParams]="{ page: pager.currentPage - 1 }" [ngClass]="{disabled:pager.currentPage == 1}" *ngIf="pager.currentPage != 1" (click)="getPaginatedResults(pager.currentPage - 1)" class="page-link">&laquo;</a>
            </li>
            <li *ngFor="let dummy of ' '.repeat(totalPages).split(''), let x = index" class="page-item number-item">
                <a routerLink="/reports" [queryParams]="{ page: x+1 }" [ngClass]="{active:pager.currentPage == x+1}" class="page-link" (click)="getPaginatedResults(x+1)">{{x+1}}</a>
            </li>
            <li class="page-item next-item">
                <a routerLink="/reports" [queryParams]="{ page: pager.currentPage + 1 }" *ngIf="pager.currentPage != totalPages" (click)="getPaginatedResults(pager.currentPage + 1)" class="page-link">&raquo;</a>
            </li>
            <li class="page-item last-item">
                <a routerLink="/reports" [queryParams]="{ page: totalPages }" *ngIf="pager.currentPage != totalPages" class="page-link" (click)="getPaginatedResults(totalPages)">Last</a>
            </li>
    </ul>

    This might not be the best implementation of the server-side pagination with MongoDB and Angular Material data tables but it works. Please feel free to share any alternate or better implementation of the server-side pagination.

  • Get Started with MongoDB on the Localhost

    In this post, we have discussed the steps required to get started with MongoDB on the localhost.

    • Download and install MongoDB from the official website.
    • In root of C directory create a folder named data and inside that folder create a new folder named db
    • Now cd into folder C:\Program Files\MongoDB\Server\4.2\bin using command prompt and run the command: mongod
    • Similarly cd into folder C:\Program Files\MongoDB\Server\4.2\bin using another command prompt and run the command: mongo
    • Now inside the second command prompt, run the command db and you will see a test DB.
    • Go into “Advanced System Settings -> Environment Variables -> Path(Under System Variables) -> Edit” and add new path i.e. C:\Program Files\MongoDB\Server\4.2\bin (change your version accordingly)
    • Now you can run the commands mongod and mongo from any directory.
    • That’s it. Now we can use MongoDB Compass to manage our MongoDB databases.

  • #03 – Components – Learn Angular From Scratch with Junaid Hassan

    In this post, we will learn about components and how to create new components in an Angular 9 application using Angular CLI. We will create the required components for our application and will show how components can be used to organize the content of the application.

    What Are Angular Components?

    An angular application is built using multiple modular pieces/sections known as components. Every component defines its own HTML, CSS, and data to be displayed on the web page. When the component data is changed then the Angular application updates only that component without reloading the whole web page.

    We can think of components as different sections of a web page. In a typical web page, we have a header, footer, and content sections. Similarly in an Angular application, a web page may have 3 components i.e. a header component, footer component, and content component. In most of the cases, the header and footer components remain the same throughout the application and only the content section is updated when the user clicks a particular menu item.

    App Component

    The app component is automatically created when we created a new Angular application using Angular CLI as we did in the previous post. The app component is comprised of 4 files like any other Angular component. The component files are available inside the folder ‘myapp/src/app’:

    • app.component.css (used to define CSS styles for the component)
    • app.component.html (used to define markup for the component)
    • app.component.spec.ts (used to define tests for the component)
    • app.component.ts (used to define and prepare data for the component)

    Create New Angular Components

    To create a new Angular component using Angular CLI, open the command prompt as an administrator and CD into the application folder. Then run the command:

    ng generate component header

    The above angular command will generate a new angular component named as the header. Go ahead and create two more components i.e. for content and footer sections.

    ng generate component content
    ng generate component footer
    Create new Angular Components - Learn Angular 9 From Scratch
    Create new Angular Components – Learn Angular 9 From Scratch

    You can find the files of these newly generated components in the folder ‘myapp/src/app’.

    In this post, we have learned about Angular components and how to create new Angular components using Angular CLI. In the next post, we will learn how to change the content of Angular components and how to merge these 3 components in the app component. Stay tuned!

  • Introduction To React Server-Side Rendering (SSR)

    In this blog post, we have discussed what is React server-side rendering, what’s the difference between client-side rendering and server-side rendering and shared some code snippets for the server-side rendered React applications.

    Client-Side Rendering (CSR)

    • The client sends a request to the server (API)
    • The server receives the request, query the requested data and sends the data back to the client
    • The client receives the data, renders the HTML and display it to the user

    Server-Side Rendering (SSR)

    • The client sends a request to the server
    • The server receives the request, query the required data, renders the HTML and sends back the rendered HTML page
    • The client receives the rendered HTML page from the server and displays it to the user

    Benefits of Server-Side Rendering

    • Improves the performance of the application
    • Improves search engine optimization (SEO) of the application

    Using Next.js Library

    Next.js is a JavaScript library that allows us to quickly set-up server-side rendered React applications. It provides some greater features like page-based routing, server-side page rendering, automatic code-splitting, client-side routing, API routes and many more…

    Steps to Create Server-Side Rendered React Application using Next.js

    • CD into the folder, where you want to create the application by using Command Prompt
    • Run the command: npm init
    • Answer the asked questions and hit Enter
    • Install the required dependencies by running the command: npm install –save next react react-dom
    • Open the application folder in your favorite code editor like VSCode
    • Open package.json file and edit the scripts object with following code (see Code Snippet 1)
    • Create a new folder inside the application folder and name it ‘pages’
    • Inside pages folder, create a new file and name it as index.js and following code (see Code Snippet 2)
    • For static files like images, create a new folder called static
    • Run the command: npm run dev
    • Your application is available at http://localhost:3000/
    • Congratulations! Your first SSR application is up and running

    Code Snippet 1:

    "scripts": {
        "dev": "next",
        "build": "next build",
        "start": "next start"
    },

    Code Snippet 2:

    export default () => (
        <p1>Hello World</p1>
    );

    To add CSS support, do the following steps:

    • Run the command: npm install –save @zeit/next-css
    • Create a new file and name it as next.config.js

    That’s it. In this post, we have created a very simple Hello World Server-Side rendered React application using Next.js.

  • #02 – Create First Angular Application – Learn Angular From Scratch with Junaid Hassan

    This is the second part of the series “Learn Angular 9 From Scratch”. In this post, we will learn how to create a new Angular application using Angular Command Line Interface i.e. Angular CLI. We will also learn about two new Angular commands i.e. ng new and ng serve. We will also test our new Angular application on localhost.

    Create a New Application

    • Open command prompt as an administrator
    • When you open the command prompt, you will be inside the directory C:\WINDOWS\System 32>
    • Change directory / CD into the folder where you want to create a new Angular application (see screenshot 1) e.g. to change the current directory to D drive, type D: and hit Enter.
    • Run the command: ng new myapp // change ‘myapp’ to whatever name you want for your application
    • Now Angular CLI will ask two questions i.e. would you like to add Angular routing? (I have selected Yes, because we will implement routing in our application) and which stylesheet format would you like to use? (I have selected CSS but you can select other format as well) [see screenshot 1]
    • After the confirmations, Angular CLI will install all necessary packages and their dependencies and will create a new Angular application inside the folder ‘myapp’
    Screenshot 1: Create a new application using the command: ng new myapp
    Screenshot 1: Create a new application using the command: ng new myapp

    Test the Application

    • Change directory / CD into folder ‘myapp’ e.g. cd myapp
    • Run the command: ng serve
    • Angular CLI will compile the application code and will serve the application on http://localhost:4200 (see screenshot 2)
    • Now you can test the application on http://localhost:4200 (see screenshot 3)
    Screenshot 2: Serve the Angular application using the command: ng serve
    Screenshot 2: Serve the Angular application using the command: ng serve
    Screenshot 3: Demo of the newly created Angular application
    Screenshot 3: Demo of the newly created Angular application

    In the next post, we will learn what are the components and how to create components in an Angular application using Angular CLI. Stay tuned!

  • #01 – Introduction – Learn Angular From Scratch with Junaid Hassan

    In this post, we will learn:

    • What is Angular?
    • What are Single Page Applications (SPA’s)?
    • What are the prerequisites to create an angular application?
    • What is NodeJS and Node Package Manager (npm)?
    • What is Angular CLI?

    What is Angular?

    Angular is a framework developed by Google to design frontend applications. The Angular converts the complete application into a single-page application (SPA). The main advantage of single-page applications (SPA’s) is that the user can access different components and pages without reloading the website. Moreover, Angular application is bundled into a single HTML, CSS and JavaScript file, which greatly improves the overall performance of the application.

    Prerequisites

    We need NodeJS and Angular CLI to create an angular application.

    • NodeJS
      • Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser
      • Node.js provides a package manager (npm) to install libraries and packages
      • We will use Node Package Manager (npm) to install Angular CLI on our computer
      • To download and install the latest stable version of node.js, visit the official website https://nodejs.org/
    • Angular CLI
      • Angular CLI or Command Line Interface is a command-line tool for creating angular applications
      • To install Angular CLI:
        • Click ‘Start Menu’
        • Type ‘cmd’ and open ‘Command Prompt’ as an administrator
        • Type the command: npm install -g @angular/cli. This command will install Angular CLI globally on your computer which means that we can run Angular commands from any directory on our computer.

    Verification

    To verify that node.js and Angular CLI are installed correctly:

    • Click ‘Start Menu’
    • Type ‘cmd’ and open ‘Command Prompt’ as an administrator
    • To check if NodeJS is installed, run the command node –version in the command prompt
    • To check if Angular CLI is installed, run the command: ng –version in the command prompt

    If node.js and Angular CLI are installed correctly, then we are all set to create our very first Angular project. In the next tutorial, we will learn how to create an Angular application using Angular CLI.

    Video Tutorial

    #01 – Introduction – Learn Angular From Scratch with Junaid Hassan
  • Introduction To Basic Git Commands

    Git/Github is a very powerful version control management tool used by the developers to manage the source code of the projects. In this blog post, we have listed all of the basic Git commands along with the short description of their usage.

    • git init (used initiate a git repository)
    • git add file-name (used to add the file to a staging environment)
    • git add . (used to add all files to a staging environment)
    • git commit -m “first version release” (used to push the changes from a staging environment to the tracked list)
    • git checkout file-name (used to get the previous version of the file back from the staging environment)
    • git reset HEAD file-name (used to un-stage the file changes)
    • git status (used to check the status of the files to be staged or the files to be committed)
    • git log (used to check the history of the commits)
    • git rm filename (used to remove the file and push the changes to a staging environment as well)
    • git checkout hash (used to get back to the previous commit by using a unique hash number)
    • git branch (used to see all branches)
    • git checkout branch-name (used to switch to the specified branch i.e. branch-name)
    • git branch branch-name (used to create a new branch named branch-name from current branch)
    • git merge branch-name (used to merge changes from branch-name into the current branch)
    • git branch -m branch-name new-name (used to rename the branch from branch-name to new-name)
    • git branch -D branch-name (used to delete the branch i.e. branch-name)
    • git clone github-url (used to clone an existing github repository from the specified URL i.e. github-url)
    • git branch -a (used to see all branches of the cloned github project)
    • git checkout -b branch-name origin/branch-name (used to switch to another branch i.e. branch-name of the cloned github project)
    • git clone –mirror github-url .git (used to clone .git folder of the github repository from the specified URL i.e. github-url)
    • git config –bool core.bare false and git reset –hard (grab all branches and copy in the current folder from the above-cloned repository)
    • git clone -b branch-name github-url (used to clone specific branch from the specified github project i.e. github-url)
  • Introduction To React Native Mobile Application Development

    The following are the points to create a simple React Native mobile application.

    • Make sure NodeJS is installed
    • Install expo-cli, globally by running the command: npm install -g expo-cli
    • If you get an error while installing the expo-cli, run the command: npx expo init
  • Profile Image Upload Functionality Using Angular and Node

    In a recent project, I was working on a user profile component that can be used by the user to edit their profile information. A part of that component was a profile image section which lets the user change their profile picture. The profile picture is sent to the Node API via HTTP Post request, stored in a folder and then name/URL of the image is stored in the database. In this post, I will share the code on how to implement this functionality.

    Form For the Profile Image

    We have created an Edit Profile component and added the following code in the edit-profile.component.html to create a form.

    <form enctype="multipart/form-data">
        <input type="file" id="profile-pic-input" (change)="detectFiles($event)" accept="image/*"/>
    </form>
    <button (click)="uploadSingle()" color="accent" [disabled]="!selectedFiles">
        <span>Upload Image</span>
    </button>

    We have created a simple form with input to grab the image file from the user. When a user clicks the “Choose File” button and selects the image file then detectFiles() method is triggered which is defined inside the edit-profile.component.ts file and it assigns the selected file to the selectedFiles variable. When the file is assigned the “Upload Image” button is enabled. When a user clicks the “Upload Image” button the uploadSingle() method is triggered which is defined in the edit-profile.component.ts file as shown below:

    Relevant Code From edit-profile.component.ts File

    //other code here
    import { HttpClient } from '@angular/common/http';
    import { HttpEvent, HttpEventType } from '@angular/common/http';
    //other code here
    selectedFiles: FileList;
    uid: number;
    constructor(private fileService: FileUploadService, private http: HttpClient) {
    //other code here
    this.uid = 123; //get the uid from the auth object
    }
    // other code here
    detectFiles(event){
      this.selectedFiles = event.target.files;
    }
    //other code here
    uploadSingle(){
      const uploadData = new FormData();
      let file = this.selectedFiles.item(0);
      if((file.size/1024/1024) < 1){ //check if file size is less than 1 MB
          let fileName = file.name;
          let idxDot = fileName.lastIndexOf(".") + 1;
          let extFile = fileName.substr(idxDot, fileName.length).toLowerCase();
          fileName = fileName + '-' + Date.now().getTime() + extFile;
          if (extFile=="jpg" || extFile=="jpeg" || extFile=="png"){
            uploadData.append('profilePicture', this.selectedFiles, this.selectedFiles.name);
            this.uploadSingleFile(this.uid, uploadData).subscribe((event: HttpEvent<any>) => {
              switch (event.type) {
                case HttpEventType.UploadProgress:
                  //track the progress here
                  break;
                case HttpEventType.Response:
                  {
                    //success
                    //update user information here
                    //show success message here
                  }
              }
            }, err => {
                 //error while uploading the image
                 //show appropriate message here
            });
          }else{
              //the uploaded image is not from the allowed image types
              //show message to user here
          }
        }else{
              //the uploaded image size is greated than 1 MB
              //show appropriate message here
        }
    }
    
    uploadSingleFile(uid, file){
        return this.http.post('http://apiurl.com/'+uid+'profile-image', file);
    }

    Most of the code is commented out for your reference. As explained earlier the detectFiles() method assigns the selected file to the appropriate variable. Then the uploadSingle() method prepares the file and calls uploadSingleFile() method which makes a POST request to our API’s endpoint (Node API) to upload the file on the server and save the URL in the database as shown below.

    NodeJS Route to Handle the Post Request

    Make sure to install multer package by running the command: npm install –save multer

    const express = require('express');
    const app = express();
    const multer = require('multer'); // handles the file uploading process
    const DIR = './uploads/user-profiles'; // where image will be uploaded
    //bootstraps the overall process for file upload
    let storage = multer.diskStorage({
      destination: (req, file, cb) => {
        cb(null, DIR);
      },
      filename: (req, file, cb) => {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
      }
    });
    let upload = multer({storage: storage});
    
    /* UPDATE user profile image information.*/
    app.post('/:id/profile-image', upload.single('profilePicture'), (req, res) => {
      if (!req.file) {
        res.status(404).json({success: false, message: 'No file received!'});
      } else {
        const sql = "UPDATE users SET ? WHERE id = ?";
        const user = {photoURL: '//'+req.headers.host+'/'+req.file.filename};
        conn.query(sql, [user, req.params.id], function (err, result) {
          if (err) return res.status(500).json({success: false, message: err.message});
          return res.status(200).send(JSON.stringify({message: "Profile image is successfuly updated!"}));
        });
      }
    });

    The multer package is used to handle the file uploading process. When the ‘/profile-image’ route receives a POST request then upload.single(‘profilePicture’) method is called a middleware that uploads the file and then inside the body of the POST request method we have saved the image URL inside the MySQL database.

    That’s it! I hope it would be helpful.