<?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: MOHSIN ALI SOOMRO</title>
    <description>The latest articles on DEV Community by MOHSIN ALI SOOMRO (@mohsinalisoomro).</description>
    <link>https://dev.to/mohsinalisoomro</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%2F480859%2Fa6187075-d50d-49f8-ba87-7827258b5cfe.jpeg</url>
      <title>DEV Community: MOHSIN ALI SOOMRO</title>
      <link>https://dev.to/mohsinalisoomro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mohsinalisoomro"/>
    <language>en</language>
    <item>
      <title>How to create stripe webhook in nextjs 13.4.4.</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Sun, 03 Sep 2023 10:52:23 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/how-to-create-stripe-webhook-in-nextjs-1344-5fn</link>
      <guid>https://dev.to/mohsinalisoomro/how-to-create-stripe-webhook-in-nextjs-1344-5fn</guid>
      <description>&lt;p&gt;As you follow this article, I think you better know about nextjs.&lt;/p&gt;

&lt;p&gt;Let's know what a webhook is.&lt;/p&gt;

&lt;p&gt;A webhook is a method of automating and integrating data or events between different applications or systems over the internet. It allows one application to send real-time information to another application or service when a specific event or trigger occurs. &lt;/p&gt;

&lt;p&gt;Remember points when you work with stripe webhook&lt;br&gt;
Wehbook accept rawbody&lt;br&gt;
It must be post request&lt;br&gt;
Event you should handle.&lt;/p&gt;

&lt;p&gt;Let's code.&lt;/p&gt;

&lt;p&gt;Create a file route.ts inside a api folder,&lt;br&gt;
api/stripe/webhook/route.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Stripe from "stripe";
import { NextRequest } from "next/server";
import { OrderTable, db } from "@/lib/drizzleOrm";
import { headers } from "next/headers";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2022-11-15",
  typescript: true,
});

export async function POST(request: NextRequest) {
  const body = await request.text();
  const endpointSecret = process.env.STRIPE_SECRET_WEBHOOK_KEY!;
  const sig = headers().get("stripe-signature") as string;
  let event: Stripe.Event;
  try {
    event = stripe.webhooks.constructEvent(body, sig, endpointSecret);
  } catch (err) {
    return new Response(`Webhook Error: ${err}`, {
      status: 400,
    });
  }

  switch (event.type) {
    case "checkout.session.async_payment_failed":
      const checkoutSessionAsyncPaymentFailed = event.data.object;
      break;
    case "checkout.session.async_payment_succeeded":
      const checkoutSessionAsyncPaymentSucceeded = event.data.object;

      break;
    case "checkout.session.completed":
      const checkoutSessionCompleted: any = event.data.object;
      const response1 = await db
        .insert(OrderTable)
        .values({
          userId: checkoutSessionCompleted?.metadata.userId,
          itemCount: 1,
          total: checkoutSessionCompleted?.amount_total as any,
          isComplete: true,
        })
        .returning();
      break;
    default:
      console.log(`Unhandled event type ${event.type}`);
  }
  return new Response("RESPONSE EXECUTE", {
    status: 200,
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break the code, &lt;/p&gt;

&lt;p&gt;await request.text() =&amp;gt; this will convert your rawbody to string&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It imports necessary modules and initializes the Stripe API with the provided secret key.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It defines an asynchronous function &lt;code&gt;POST(request: NextRequest)&lt;/code&gt; that will handle incoming HTTP POST requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Inside the function:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It extracts the request body and the Stripe webhook signature.&lt;/li&gt;
&lt;li&gt;It attempts to construct a Stripe event from the request data using the Stripe library.&lt;/li&gt;
&lt;li&gt;If there's an error during event construction, it returns a 400 Bad Request response with an error message.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It then checks the type of the Stripe event and performs different actions based on the event type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For "checkout.session.async_payment_failed," it does nothing specific.&lt;/li&gt;
&lt;li&gt;For "checkout.session.async_payment_succeeded," it does nothing specific.&lt;/li&gt;
&lt;li&gt;For "checkout.session.completed," it inserts an order record into a database table using the Drizzle ORM library.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It logs an error message for any unhandled event types.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, it returns a 200 OK response with the message "RESPONSE EXECUTE" to acknowledge the webhook execution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a webhook calls it saves record in database if checkout session complete. For other events you should follow according &lt;/p&gt;

&lt;p&gt;Now how to test  webhook,&lt;br&gt;
You can test webhook on localhost &lt;br&gt;
&lt;a href="https://stripe.com/docs/webhooks" rel="noopener noreferrer"&gt;https://stripe.com/docs/webhooks&lt;/a&gt;&lt;br&gt;
Go to stripe =&amp;gt; developer =&amp;gt; webhook &lt;br&gt;
&lt;a href="https://dashboard.stripe.com/test/webhooks/create" rel="noopener noreferrer"&gt;https://dashboard.stripe.com/test/webhooks/create&lt;/a&gt;&lt;br&gt;
Here you will get test key for localhost &lt;/p&gt;

&lt;p&gt;Note: Webhook localhost key and production key are different, localhost key you will get on webhook page, for production get you have to register key webhook, and click on reveal you will get a webhook production key&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pmckuqgexqfddu5mk96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0pmckuqgexqfddu5mk96.png" alt="image for stripe webhook key reveal" width="800" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading&lt;/p&gt;

</description>
      <category>stripe</category>
      <category>webhook</category>
      <category>nextjs</category>
      <category>api</category>
    </item>
    <item>
      <title>Splitting a PDF file into multiple files using AWS Lambda and Node.js</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Thu, 09 Feb 2023 13:10:43 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/splitting-a-pdf-file-into-multiple-files-using-aws-lambda-and-nodejs-3o3n</link>
      <guid>https://dev.to/mohsinalisoomro/splitting-a-pdf-file-into-multiple-files-using-aws-lambda-and-nodejs-3o3n</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PDFDocument&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pdf-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;S3&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;PDFDocument&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Records&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Records&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;KEy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;record&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PDF BODY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfDoc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;event&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pdf&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;promises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;pdfDoc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getPages&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create a new "sub" document&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;PDFDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// copy the page at current index&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;copiedPage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;subDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;copyPages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pdfDoc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="nx"&gt;subDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addPage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;copiedPage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfBytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;subDocument&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;splitFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SPLIT NAME&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;splitFile&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;putObject&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;splitedfile&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;splitFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pdfBytes&lt;/span&gt;
        &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promises&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;response&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PDF file split and saved to S3 successfully.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;&lt;span class="s2"&gt;`

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

&lt;/div&gt;



&lt;p&gt;This is an AWS Lambda function written in Node.js which is used to split a PDF file into multiple PDF files, one for each page of the original file.&lt;/p&gt;

&lt;h3&gt;
  
  
  The code first imports three libraries:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;fs (File System): A built-in library in Node.js used to work with the file system of the system on which the code is running. In this code, it is not being used.&lt;/li&gt;
&lt;li&gt;AWS (Amazon Web Services) from 'aws-sdk': A library for working with Amazon Web Services. In this code, it is used to interact with Amazon S3 (Simple Storage Service), a cloud-based object storage service.&lt;/li&gt;
&lt;li&gt;PDFDocument from 'pdf-lib': A library for working with PDF (Portable Document Format) files. In this code, it is used to load and manipulate PDF files.
Then, an instance of the S3 client is created using new AWS.S3(). This instance will be used to interact with the S3 service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main logic of the function is inside the handler function. This function will be called when the AWS Lambda is triggered.&lt;/p&gt;

&lt;p&gt;The function starts by logging the event object, which is passed as an argument. This event object contains information about the event that triggered the function. In this case, it should contain information about the S3 object that was just created or updated.&lt;/p&gt;

&lt;p&gt;Then, the name of the S3 bucket and the key of the object are extracted from the event object. The key represents the path of the object in the S3 bucket.&lt;/p&gt;

&lt;p&gt;The function then uses the s3.getObject method to get the contents of the PDF file from the S3 bucket. The method is passed an object with two properties, Bucket and Key, which represent the name of the S3 bucket and the key of the object, respectively.&lt;/p&gt;

&lt;p&gt;Once the contents of the PDF file are retrieved, the function uses the PDFDocument.load method to load the PDF document.&lt;/p&gt;

&lt;p&gt;The function then creates an array of promises, where each promise represents a task to split one page of the PDF document into a separate file and save it to S3.&lt;/p&gt;

&lt;p&gt;For each page in the PDF document, the function creates a new PDF document using the PDFDocument.create method. Then, it uses the copyPages method to copy the page from the original document to the new document. Finally, it uses the save method to save the new document as a new PDF file. The contents of the new file are then uploaded to S3 using the s3.putObject method.&lt;/p&gt;

&lt;p&gt;Once all the promises are fulfilled, the function returns a message indicating that the PDF file has been split and saved to S3 successfully.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>New Stack Nextjs, Prisma, Typescript and trpc</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Tue, 10 Jan 2023 19:05:10 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/new-stack-nextjs-prisma-typescript-and-trpc-5gn5</link>
      <guid>https://dev.to/mohsinalisoomro/new-stack-nextjs-prisma-typescript-and-trpc-5gn5</guid>
      <description>&lt;p&gt;Building web applications can be a challenging task, but with the right tools, it can be made much easier. One such toolset is the combination of Next.js, Prisma, TypeScript, TRPC, and MySQL. Together, these technologies offer a powerful and flexible solution for building high-performance web applications.&lt;/p&gt;

&lt;p&gt;Next.js is a popular framework for building server-rendered React applications. It provides a set of features that make it easy to build scalable and performant web apps, such as automatic code splitting, hot module replacement, and support for server-side rendering. This makes it ideal for building web apps that need to handle a lot of traffic or have a lot of dynamic content.&lt;/p&gt;

&lt;p&gt;Prisma is an Object-Relational Mapping (ORM) tool that makes it easy to work with databases in your TypeScript code. With Prisma, you can define your database schema using a simple data definition language (DDL) and then use that schema to interact with your database using a set of generated TypeScript functions. This removes the need to write raw SQL queries and allows you to interact with your database in an object-oriented way.&lt;/p&gt;

&lt;p&gt;TypeScript is a superset of JavaScript that adds optional static typing, making it easier to write maintainable and error-free code. It also includes features like interfaces, classes, and decorators, which can help you to write more elegant and expressive code. With the help of TypeScript, it becomes more easy to refactor the code and maintain it.&lt;/p&gt;

&lt;p&gt;TRPC (Transport Layer Security Remote Procedure Call) is a way to make remote procedure calls to backend services over a secure connection. It is a way to send a message from the client to the server and get a response. This makes the communication over network much more secure and reliable.&lt;/p&gt;

&lt;p&gt;Finally, MySQL is a popular open-source relational database management system. It is widely used for web and enterprise applications and it offers many features such as triggers, stored procedures, views, and more. With MySQL, you can easily store, retrieve, and manage large amounts of data.&lt;/p&gt;

&lt;p&gt;By using these technologies together, you can build web applications that are fast, reliable, and easy to maintain. The combination of Next.js, Prisma, TypeScript, TRPC and MySQL offers a powerful and flexible solution for building high-performance web applications.&lt;/p&gt;

&lt;p&gt;In conclusion, using these technologies together can help you create a robust web application that is easy to maintain, performs well, and is more secure and reliable. Whether you're a beginner or an experienced developer, these tools can help you create great web apps quickly and easily.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>gratitude</category>
    </item>
    <item>
      <title>Bad control character in string literal in JSON at position 190 amplify UI</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Sat, 26 Nov 2022 15:29:35 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/bad-control-character-in-string-literal-in-json-at-position-190-amplify-ui-19i8</link>
      <guid>https://dev.to/mohsinalisoomro/bad-control-character-in-string-literal-in-json-at-position-190-amplify-ui-19i8</guid>
      <description>&lt;p&gt;This error like a monster in amplify UI library, it takes 2 days to solve it, just replace from "🔒Icon" to "Icon" and boom solved&lt;/p&gt;

&lt;p&gt;Reference github issue&lt;br&gt;
&lt;a href="https://github.com/aws-amplify/amplify-adminui/issues/658" rel="noopener noreferrer"&gt;https://github.com/aws-amplify/amplify-adminui/issues/658&lt;/a&gt;&lt;/p&gt;

</description>
      <category>emptystring</category>
    </item>
    <item>
      <title>Make Interactive button using css</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Sun, 03 Jul 2022 07:48:14 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/make-interactive-button-using-css-50e3</link>
      <guid>https://dev.to/mohsinalisoomro/make-interactive-button-using-css-50e3</guid>
      <description>&lt;p&gt;Make interactive button&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Cob52Ogk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yagabd7yd5da0q8z5x4f.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Cob52Ogk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yagabd7yd5da0q8z5x4f.gif" alt="inteactive gif" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;HTML&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;div className="App"&amp;gt;
      &amp;lt;button&amp;gt;button&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* {
  padding: 0px;
  margin: 0px;
}
.App {
  font-family: sans-serif;
  text-align: center;
  background-color: #e0e0e0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
button {
  background: #e0e0e0;
  box-shadow: 20px 20px 60px #bebebe, -20px -20px 60px #ffffff;
  background-color: #e0e0e0;
  border: none;
  border-radius: 50px;
  width: 200px;
  height: 200px;
}
button:active {
  border-radius: 50px;
  background: #e0e0e0;
  box-shadow: inset 20px 20px 60px #bebebe, inset -20px -20px 60px #ffffff;
}

button:focus {
  border-radius: 50px;
  background: #e0e0e0;
  box-shadow: inset 20px 20px 60px #bebebe, inset -20px -20px 60px #ffffff;
}

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

&lt;/div&gt;



&lt;p&gt;Thanks.&lt;/p&gt;

</description>
      <category>css</category>
      <category>react</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Prefer more precise alternative to the string Types in Typescript</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Sun, 03 Jul 2022 07:29:05 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/prefer-more-precise-alternative-to-the-string-types-in-typescript-4jbj</link>
      <guid>https://dev.to/mohsinalisoomro/prefer-more-precise-alternative-to-the-string-types-in-typescript-4jbj</guid>
      <description>&lt;p&gt;The domain of string type is big&lt;/p&gt;

&lt;p&gt;Suppose you're building music collection and you want to define a type for an album&lt;/p&gt;

&lt;p&gt;Attemp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Album{
 artist:string;
 title:string;
 releaseDate:string; //YYYY-MM-DD
 recordingType:string; // "live" or "studio"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The prevelance of string types and the type information in comments are strong indications that this interface isn't quite right. Here is what can go wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const kindOfBlue:Album ={
 artist:"Miles Devid",
 title:"Kind of blue",
 releaseDate:"auguest 17th 1959",
 recordingType:"Studio",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem 1:&lt;/strong&gt;&lt;br&gt;
Date is not formated&lt;br&gt;
&lt;strong&gt;Problem 2:&lt;/strong&gt;&lt;br&gt;
recordingType Studio is small spell but it is capital.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to narrow down string and solve these problem?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type RecordingType="studio" | "live" 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Album{
 artist:string;
 title:string;
 releaseDate:Date; 
 recordingType:RecordingType; 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const kindOfBlue:Album ={
 artist:"Miles Devid",
 title:"Kind of blue",
 releaseDate:new Date("1959-08-18"),
 recordingType:"studio",
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these changes Typescript is able to do a more thorough check for errors&lt;/p&gt;

&lt;p&gt;Make more precise type to error pron the code.&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Upload mutiple image component and get base64 format</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Thu, 17 Mar 2022 08:12:50 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/upload-mutiple-image-component-and-get-base64-format-17pa</link>
      <guid>https://dev.to/mohsinalisoomro/upload-mutiple-image-component-and-get-base64-format-17pa</guid>
      <description>&lt;p&gt;Dependencies&lt;br&gt;
react &lt;br&gt;
tailwind&lt;br&gt;
react-icons&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 from "react";
import { AiFillCloseSquare } from "react-icons/ai";

function MultipleImageUploadComponent({ images, setImages }) {
  const handleImageChange = ({ target }) =&amp;gt; {
    for (let img of target.files) {
      const fileReader = new FileReader();
      fileReader.readAsDataURL(img);
      fileReader.onload = function () {
        setImages((prev) =&amp;gt; [...prev, fileReader.result]);
      };
    }
  };

  const removeImage = (img) =&amp;gt; {
    const rmImg = images?.filter((d) =&amp;gt; d !== img);
    setImages(rmImg);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;main className="container mx-auto max-w-screen-lg h-full border border-1 mt-4"&amp;gt;
        &amp;lt;article
          aria-label="File Upload Modal"
          className="relative h-full flex flex-col bg-white  rounded-md"
          onDrop={(e) =&amp;gt; console.log("onDrop", e)}
          onDragOver={(e) =&amp;gt; console.log("onDragOver", e)}
          onDragLeave={(e) =&amp;gt; console.log("onDragLeave", e)}
          onDragEnter={(e) =&amp;gt; console.log("onDragEnter", e)}
        &amp;gt;
          &amp;lt;div
            id="overlay"
            className="w-full h-full absolute top-0 left-0 pointer-events-none z-50 flex flex-col items-center justify-center rounded-md"
          &amp;gt;
            &amp;lt;i&amp;gt;
              &amp;lt;svg
                className="fill-current w-12 h-12 mb-3 text-blue-700"
                xmlns="http://www.w3.org/2000/svg"
                width="24"
                height="24"
                viewBox="0 0 24 24"
              &amp;gt;
                &amp;lt;path d="M19.479 10.092c-.212-3.951-3.473-7.092-7.479-7.092-4.005 0-7.267 3.141-7.479 7.092-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408zm-7.479-1.092l4 4h-3v4h-2v-4h-3l4-4z" /&amp;gt;
              &amp;lt;/svg&amp;gt;
            &amp;lt;/i&amp;gt;
          &amp;lt;/div&amp;gt;

          &amp;lt;section className="overflow-auto p-8 w-full h-full flex flex-col"&amp;gt;
            &amp;lt;header className="border-dashed border-2 border-gray-400 py-12 flex flex-col justify-center items-center"&amp;gt;
              &amp;lt;p className="mb-3 font-semibold text-gray-900 flex flex-wrap justify-center"&amp;gt;&amp;lt;/p&amp;gt;
              &amp;lt;input
                type="file"
                accept="image/*"
                id="file"
                multiple
                className="hidden"
                onChange={handleImageChange}
              /&amp;gt;
              &amp;lt;label
                htmlFor="file"
                className="mt-2 rounded-sm px-3 py-1 bg-gray-200 hover:bg-gray-300 focus:shadow-outline focus:outline-none"
              &amp;gt;
                Upload images
              &amp;lt;/label&amp;gt;
            &amp;lt;/header&amp;gt;

            &amp;lt;h1 className="pt-8 pb-3 font-semibold sm:text-lg text-gray-900"&amp;gt;
              To Upload
            &amp;lt;/h1&amp;gt;

            {images &amp;amp;&amp;amp; images?.length ? (
              &amp;lt;div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2  border border-1"&amp;gt;
                {images?.map((img) =&amp;gt; (
                  &amp;lt;div className="w-full  text-center relative flex flex-row justify-center items-center"&amp;gt;
                    &amp;lt;img className="mx-auto w-full h-32" src={img} alt={img} /&amp;gt;
                    &amp;lt;span
                      onClick={() =&amp;gt; removeImage(img)}
                      className="absolute top-0 right-0 text-purple-500 cursor-pointer"
                    &amp;gt;
                      &amp;lt;AiFillCloseSquare size={20} /&amp;gt;
                    &amp;lt;/span&amp;gt;
                  &amp;lt;/div&amp;gt;
                ))}
              &amp;lt;/div&amp;gt;
            ) : (
              &amp;lt;div className="w-full flex justify-center items-center border border-1"&amp;gt;
                &amp;lt;img
                  className="text-center w-32 mt-4"
                  src="https://user-images.githubusercontent.com/507615/54591670-ac0a0180-4a65-11e9-846c-e55ffce0fe7b.png"
                  alt="no data"
                /&amp;gt;
              &amp;lt;/div&amp;gt;
            )}
          &amp;lt;/section&amp;gt;
        &amp;lt;/article&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default MultipleImageUploadComponent;

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

&lt;/div&gt;



&lt;h1&gt;
  
  
  Output
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4uhrgdoz2ottsz4rvsg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4uhrgdoz2ottsz4rvsg.png" alt="Output"&gt;&lt;/a&gt; &lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>component</category>
    </item>
    <item>
      <title>Send email with nodemailer</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Mon, 07 Feb 2022 08:00:18 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/send-email-with-nodemailer-nn3</link>
      <guid>https://dev.to/mohsinalisoomro/send-email-with-nodemailer-nn3</guid>
      <description>&lt;p&gt;Enable these &lt;br&gt;
&lt;a href="https://myaccount.google.com/lesssecureapps"&gt;lesssecure&lt;/a&gt;&lt;br&gt;
&lt;a href="https://accounts.google.com/b/0/DisplayUnlockCaptcha"&gt;DisplayUnlockCaptcha&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import nodemailer from "nodemailer";
async function sendEmail(to, subject, text) {
  try {
    const transport = nodemailer.createTransport({
      port: 587,
      host: "smtp.gmail.com",
      auth: {
        user: "&amp;lt;Your Email&amp;gt;",
        pass: "&amp;lt;Your Password&amp;gt;",
      },
    });
    const option = {
      from: "&amp;lt;Email&amp;gt;",
      to: to,
      subject: subject,
      text: text,
    };
    const result = await transport.sendMail(option);
    console.log("function", { result });
    return result;
  } catch (error) {
    return error;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Track Scroll event in reactjs</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Tue, 25 Jan 2022 12:37:53 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/scroll-event-on-div-in-reacjts-552d</link>
      <guid>https://dev.to/mohsinalisoomro/scroll-event-on-div-in-reacjts-552d</guid>
      <description>&lt;p&gt;Code...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; import { useState } from "react";
import "./styles.css";

export default function App() {
  const [scroll, setScroll] = useState(0);
  const onScroll = () =&amp;gt; {
    const scrollY = window?.scrollY;
    const scrollTop = document.getElementById("test").scrollTop;

    setScroll(scrollTop);
  };
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;h1&amp;gt;Scroll Position {scroll}&amp;lt;/h1&amp;gt;
      &amp;lt;div
        id="test"
        onScroll={onScroll}
        style={{
          backgroundColor: "white",
          zIndex: "100",
          height: "200px",
          overflowY: "scroll"
        }}
      &amp;gt;
        content...
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://codesandbox.io/s/autumn-framework-yn2tj?file=/src/App.js:0-2554"&gt;Codesandbox&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>html</category>
      <category>programming</category>
    </item>
    <item>
      <title>Create Google Application for google Oauth2</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Thu, 23 Dec 2021 09:12:33 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/create-google-application-for-google-oauth2-9ib</link>
      <guid>https://dev.to/mohsinalisoomro/create-google-application-for-google-oauth2-9ib</guid>
      <description>&lt;h2&gt;
  
  
  Step for create google app and get client id and secret key
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Visit this link and login with your email&lt;/li&gt;
&lt;li&gt;&lt;a href="https://console.cloud.google.com/apis/dashboard"&gt;https://console.cloud.google.com/apis/dashboard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create your project in given link&lt;/li&gt;
&lt;li&gt;User Type External&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Click the option (OAuth consent screen)&lt;/li&gt;
&lt;li&gt;Fill these fields&lt;/li&gt;
&lt;li&gt;App name : (AppName)&lt;/li&gt;
&lt;li&gt;User support email: YourEmail&lt;/li&gt;
&lt;li&gt;Authorized domains: Enter this (example.com)&lt;/li&gt;
&lt;li&gt;Developer email : (DEV EMAIL)&lt;/li&gt;
&lt;li&gt;Publish the app&lt;/li&gt;
&lt;li&gt;Leave Rest of the fields&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Click Crendentials&lt;/li&gt;
&lt;li&gt;Click Create Crendentials (Create OAuth client ID)&lt;/li&gt;
&lt;li&gt;Application type: Web Applications&lt;/li&gt;
&lt;li&gt;Name : AppName&lt;/li&gt;
&lt;li&gt;Authorized JavaScript origins : Enter This (&lt;a href="https://example.com"&gt;https://example.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Authorized redirect URIs : &lt;a href="https://example.com/"&gt;https://example.com/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Final
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;It will give you client id and secret&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>infinity scroll down reactjs</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Fri, 10 Dec 2021 12:22:11 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/infinity-scroll-down-reactjs-1599</link>
      <guid>https://dev.to/mohsinalisoomro/infinity-scroll-down-reactjs-1599</guid>
      <description>&lt;p&gt;Code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useCallback, useEffect, useState } from "react";
import "./styles.css";
import InfiniteScroll from "react-infinite-scroll-component";
export default function App() {
  const [state, setState] = useState([]);
  const [data, setData] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const [perPage] = useState(20);
  const [currentPage, setCurrentPage] = useState(1);
  const lastIndex = currentPage * perPage;
  const firstIndex = lastIndex - perPage;

  const fetchPost = async () =&amp;gt; {
    const json = await fetch("https://jsonplaceholder.typicode.com/posts");
    const result = await json.json();
    setState(result);
  };

  const fetchMore = useCallback(() =&amp;gt; {
    setTimeout(() =&amp;gt; {
      setCurrentPage(currentPage + 1);
      let d = [...state].slice(firstIndex, lastIndex);
      setData((prev) =&amp;gt; [...prev, ...d]);
    }, 1000);
  },[state])

  useEffect(() =&amp;gt; {
    fetchPost();
    if (state.length) fetchMore();
  }, []);

  useEffect(() =&amp;gt; {
    if (data.length &amp;lt; state.length) {
      setHasMore(true);
    } else {
      setHasMore(false);
    }
  }, [state]);
  console.log({ state, data, lastIndex, firstIndex, currentPage });
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;h1&amp;gt;Hello CodeSandbox&amp;lt;/h1&amp;gt;
      &amp;lt;h2&amp;gt;Start editing to see some magic happen!&amp;lt;/h2&amp;gt;

      &amp;lt;InfiniteScroll
        dataLength={data.length}
        next={fetchMore}
        hasMore={hasMore}
        loader={&amp;lt;h4&amp;gt;Loading...&amp;lt;/h4&amp;gt;}
        scrollableTarget="scrollableDiv"
      &amp;gt;
        {data.length &amp;amp;&amp;amp;
          data.map((post) =&amp;gt; {
            return (
              &amp;lt;div
                style={{
                  backgroundColor: "green ",
                  padding: "10px",
                  margin: "10px"
                }}
              &amp;gt;
                {post.title}
              &amp;lt;/div&amp;gt;
            );
          })}
      &amp;lt;/InfiniteScroll&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

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

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>html</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My first job interview question?</title>
      <dc:creator>MOHSIN ALI SOOMRO</dc:creator>
      <pubDate>Wed, 08 Dec 2021 13:19:57 +0000</pubDate>
      <link>https://dev.to/mohsinalisoomro/my-first-job-interview-question-47l9</link>
      <guid>https://dev.to/mohsinalisoomro/my-first-job-interview-question-47l9</guid>
      <description>&lt;p&gt;How to get loop throw and structure data.&lt;br&gt;
loop throw questions array and get comments with respect of the &lt;code&gt;questionId&lt;/code&gt; and replies with respect of &lt;code&gt;commentId&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let data = {
    questions: [
        {
            questionId: 1,
            questionText: "Question 1",
        },
        {
            questionId: 2,
            questionText: "Question 2",
        },
        {
            questionId: 3,
            questionText: "Question 3",
        },
        {
            questionId: 4,
            questionText: "Question 4",
        },
    ],
    comments: [
        {
            commentId: 1,
            questionId: 1,
            commentText: "Comment 1",
        },
        {
            commentId: 2,
            questionId: 1,
            commentText: "Comment 2",
        },
        {
            commentId: 3,
            questionId: 1,
            commentText: "Comment 3",
        },
        {
            commentId: 4,
            questionId: 3,
            commentText: "Comment 4",
        },
        {
            commentId: 5,
            questionId: 2,
            commentText: "Comment 5",
        },
    ],
    replies: [
        {
            commentId: 1,
            replyId: 1,
            replyText: "Reply 1",
        },
        {
            commentId: 2,
            replyId: 2,
            replyText: "Reply 2",
        },
        {
            commentId: 3,
            replyId: 3,
            replyText: "Reply 3",
        },
        {
            commentId: 3,
            replyId: 4,
            replyText: "Reply 4",
        },
        {
            commentId: 5,
            replyId: 5,
            replyText: "Reply 5",
        },
    ],
};

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

&lt;/div&gt;



&lt;p&gt;Try yourself to prepare interview if stuck blow is the solution&lt;br&gt;
Desire output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    questions: { questionId: 1, questionText: 'Question 1' },
    comments: { commentId: 1, questionId: 1, commentText: 'Comment 1' },
    replies: [ [Object] ]
  },
  {
    questions: { questionId: 1, questionText: 'Question 1' },
    comments: { commentId: 2, questionId: 1, commentText: 'Comment 2' },
    replies: [ [Object] ]
  },
  {
    questions: { questionId: 1, questionText: 'Question 1' },
    comments: { commentId: 3, questionId: 1, commentText: 'Comment 3' },
    replies: [ [Object], [Object] ]
  },
  {
    questions: { questionId: 2, questionText: 'Question 2' },
    comments: { commentId: 5, questionId: 2, commentText: 'Comment 5' },
    replies: [ [Object] ]
  },
  {
    questions: { questionId: 3, questionText: 'Question 3' },
    comments: { commentId: 4, questionId: 3, commentText: 'Comment 4' },
    replies: []
  }
]

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solution 👏 👏 👏
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function generateOutput(data) {
    const { questions, comments, replies } = data;
    // CODE HERE
    let output = [];
  questions.map((i)=&amp;gt;{
      comments.map((c)=&amp;gt;{
        const reply = replies.filter((r)=&amp;gt;r.commentId===c.commentId)
        if(c.questionId===i.questionId){
          output.push({questions:i,comments:c,replies:reply})
        }
      })
  })
    return output;
}

let output = generateOutput(data);

console.log(output);

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

&lt;/div&gt;



&lt;p&gt;Thanks for reading, if it is helpful comment blow with Thanks 😃&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
