<?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: Tejas Naigaonkar</title>
    <description>The latest articles on DEV Community by Tejas Naigaonkar (@jastya).</description>
    <link>https://dev.to/jastya</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%2F3290367%2Fbc0bf97f-3c80-437d-a0e5-9e303330385d.png</url>
      <title>DEV Community: Tejas Naigaonkar</title>
      <link>https://dev.to/jastya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jastya"/>
    <language>en</language>
    <item>
      <title>Export to excel in Angular app without using any library</title>
      <dc:creator>Tejas Naigaonkar</dc:creator>
      <pubDate>Sat, 23 Aug 2025 17:14:01 +0000</pubDate>
      <link>https://dev.to/jastya/export-to-excel-in-angular-app-without-using-any-library-n7k</link>
      <guid>https://dev.to/jastya/export-to-excel-in-angular-app-without-using-any-library-n7k</guid>
      <description>&lt;p&gt;Code to implement export to excel in Angular app.&lt;/p&gt;

&lt;p&gt;It’s gonna be typesafe code.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interface ExcelRow&amp;lt;T&amp;gt; {[key: string]: T;}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface Column&amp;lt;T&amp;gt; {
  header: string;
  key: keyof T;
  type: 'string' | 'number';
}
&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;exportToExcel() {
    const maxLength: Record&amp;lt;string, number&amp;gt; = this.columns.reduce(
      (acc: Record&amp;lt;string, number&amp;gt;, col: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;) =&amp;gt; {
        acc[col.key] = 0;
        return acc;
      },
      {}
    );

    this.data.forEach((data: ExcelRow&amp;lt;number | string&amp;gt;) =&amp;gt; {
      this.columns.forEach((column: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;) =&amp;gt; {
        const val: string | number = data[column.key];
        const length: number = ('' + val).toString().length;
        maxLength[column.key] = Math.max(maxLength[column.key], length);
      });
    });

    const colWidths: Record&amp;lt;string, string&amp;gt; = this.columns.reduce(
      (acc: Record&amp;lt;string, string&amp;gt;, col: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;) =&amp;gt; {
        acc[col.key] = `${maxLength[col.key] * 80}%`;
        return acc;
      },
      {}
    );

    let htmlContent = `
      &amp;lt;html&amp;gt;
        &amp;lt;head&amp;gt;
          &amp;lt;meta charset="UTF-8"&amp;gt;
        &amp;lt;/head&amp;gt;
        &amp;lt;body&amp;gt;
          &amp;lt;table border="1"&amp;gt;
            &amp;lt;tr&amp;gt;
              ${this.columns
                .map(
                  (column: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;) =&amp;gt;
                    `&amp;lt;th style="width: ${colWidths[column.key]}"&amp;gt;${
                      column.header
                    }&amp;lt;/th&amp;gt;`
                )
                .join('')}
    `;

    this.data.forEach((data: ExcelRow&amp;lt;number | string&amp;gt;) =&amp;gt; {
      htmlContent += `
            &amp;lt;/tr&amp;gt;
            ${this.columns
              .map(
                (column: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;) =&amp;gt; `
          &amp;lt;td&amp;gt;${data[column.key]}&amp;lt;/td&amp;gt;
        `
              )
              .join('')}
    `;
    });

    htmlContent += `
    &amp;lt;/table&amp;gt;
    &amp;lt;/body&amp;gt;
  &amp;lt;/html&amp;gt;
  `;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example column and data to export -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  data: ExcelRow&amp;lt;number | string&amp;gt;[] = [
    {
      id: 7,
      name: 'John Doe',
      work: 'Developer',
      address: '7, Village Road, KA',
    },
    {
      id: 8,
      name: 'Alice',
      work: 'QA Engg',
      address: '7, Village Road, LA',
    },
    {
      id: 9,
      name: 'Maya',
      work: 'Manager',
      address: '7, Village Road, MH',
    },
  ];

  columns: Column&amp;lt;ExcelRow&amp;lt;number | string&amp;gt;&amp;gt;[] = [
    {
      header: 'ID',
      key: 'id',
      type: 'number',
    },
    {
      header: 'Name',
      key: 'name',
      type: 'string',
    },
    {
      header: 'Work',
      key: 'work',
      type: 'string',
    },
    {
      header: 'Address',
      key: 'address',
      type: 'string',
    },
  ];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the below example implemented in stackblitz for exporting array of objects without using any library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/angular-tooxsa9w" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/angular-tooxsa9w&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>exporttoexcel</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Generic code to export array of objects (table data) into excel using XLSX library</title>
      <dc:creator>Tejas Naigaonkar</dc:creator>
      <pubDate>Sat, 23 Aug 2025 10:00:20 +0000</pubDate>
      <link>https://dev.to/jastya/generic-code-to-export-array-of-objects-table-data-into-excel-using-xlsx-library-2k3a</link>
      <guid>https://dev.to/jastya/generic-code-to-export-array-of-objects-table-data-into-excel-using-xlsx-library-2k3a</guid>
      <description>&lt;p&gt;Consider we have an array of objects which is to exported into an excel using &lt;a href="https://www.npmjs.com/package/xlsx" rel="noopener noreferrer"&gt;XLSX library&lt;/a&gt; we can use some simple code like below -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as XLSX from 'xlsx';

exportAsExcelFile(data: any[], fileName: string): void {
    const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(json);
    const workbook: XLSX.WorkBook = {
      Sheets: { 'data': worksheet },
      SheetNames: ['data']
    };
  XLSX.writeFile(workbook, `${filename}.xlsx`);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Issues with above code&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No type safety&lt;/li&gt;
&lt;li&gt;Exported excel displays data in default cell width. If a cell contains data that exceeds the default cell width, it does not look good.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's solve above issues - &lt;/p&gt;

&lt;p&gt;Use below interface and the code&lt;br&gt;
&lt;code&gt;interface ExcelRow {[key: string]: string;}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as XLSX from 'xlsx';

exportAsExcelFile(data: ExcelRow[], fileName: string): void {
    const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data);
    const workbook: XLSX.WorkBook = {
      Sheets: { data: worksheet },
      SheetNames: ['data'],
    };

    const columnWidths: XLSX.ColInfo[] = Object.keys(data[0]).map(
      (key: keyof ExcelRow) =&amp;gt; {
        const maxLength = Math.max(
          ('' + key).length,
          ...data.map((row: ExcelRow) =&amp;gt;
            row[key] ? row[key].toString().length : 0
          )
        );
        return { wch: maxLength + 2 }; // Adding some padding
      }
    );

    worksheet['!cols'] = columnWidths;

    XLSX.writeFile(workbook, `${fileName}.xlsx`);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added type safety and the exported excel has cell width adjusted dynamically as per the cell data.&lt;/p&gt;

&lt;p&gt;We can use method &lt;code&gt;exportAsExcelFile()&lt;/code&gt; by passing data like below in our component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data: ExcelRow[] = [
      {
        ID: '007',
        NAME: 'John Doe',
        Work: 'Developer',
        Address: '7, Village Road, KA'
      },
      {
        ID: '008',
        NAME: 'Alice',
        Work: 'QA Engg',
        Address: '7, Village Road, LA'
      },
      {
        ID: '009',
        NAME: 'Maya',
        Work: 'Manager',
        Address: '7, Village Road, MH'
      },
    ];
    this.exportAsExcelFile(data, 'Employee data');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above code works. Notice that the above code is available in a component; what if &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This export functionality needs to be used in many other components in the app. &lt;/li&gt;
&lt;li&gt;The type of the data value in the &lt;code&gt;ExcelRow&lt;/code&gt;can be something other than &lt;code&gt;string&lt;/code&gt;; it can be a &lt;code&gt;number&lt;/code&gt;, &lt;code&gt;null&lt;/code&gt; etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This can be achieved by&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Copy pasting the same code in all component wherever it is required - works but not a good standard&lt;/li&gt;
&lt;li&gt;Create a utility class and use this code which then can be used by components who need it. And using generic type of data in &lt;code&gt;ExcelRow&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's create a utility method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;interface ExcelRow&amp;lt;T&amp;gt; {[key: string]: T;}&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  exportAsExcelFile&amp;lt;T&amp;gt;(data: ExcelRow&amp;lt;T&amp;gt;[], fileName: string): void {
    const worksheet: XLSX.WorkSheet = XLSX.utils.json_to_sheet(data);
    const workbook: XLSX.WorkBook = {
      Sheets: { data: worksheet },
      SheetNames: ['data'],
    };

    const columnWidths: XLSX.ColInfo[] = Object.keys(data[0]).map(
      (key: keyof ExcelRow&amp;lt;T&amp;gt;) =&amp;gt; {
        const maxLength = Math.max(
          ('' + key).length,
          ...data.map((row: ExcelRow&amp;lt;T&amp;gt;) =&amp;gt;
            row[key] ? row[key].toString().length : 0
          )
        );
        return { wch: maxLength + 2 }; // Adding some padding
      }
    );

    worksheet['!cols'] = columnWidths;

    XLSX.writeFile(workbook, `${fileName}.xlsx`);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below are the examples of data -&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    const data: ExcelRow&amp;lt;string | number | null&amp;gt;[] = [
      {
        ID: 7,
        NAME: 'John Doe',
        Work: 'Developer',
        Address: '7, Village Road, KA'
      },
      {
        ID: 8,
        NAME: 'Alice',
        Work: 'QA Engg',
        Address: '7, Village Road, LA'
      },
      {
        ID: '009',
        NAME: 'Maya',
        Work: 'Manager',
        Address: null
      },
    ];
&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 data2: ExcelRow&amp;lt;number&amp;gt;[] = [
      {
        'Student ID': 1,
        Score: 90,
      },
      {
        'Student ID': 2,
        Score: 95,
      },
    ];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way we have a utility that can be used to export array of objects into excel using XLSX library.&lt;/p&gt;

&lt;p&gt;I hope this helps.&lt;/p&gt;

&lt;p&gt;Thanks,&lt;br&gt;
Jastya!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>exporttoexcel</category>
      <category>xlsx</category>
    </item>
    <item>
      <title>Tic Toc Toe</title>
      <dc:creator>Tejas Naigaonkar</dc:creator>
      <pubDate>Thu, 24 Jul 2025 06:55:35 +0000</pubDate>
      <link>https://dev.to/jastya/tic-toc-toe-2gif</link>
      <guid>https://dev.to/jastya/tic-toc-toe-2gif</guid>
      <description>&lt;p&gt;Click the link to play Tic-Tac-Toe&lt;br&gt;
&lt;a href="https://tic-tac-j522t95x1-tejas-projects-d428ea49.vercel.app/" rel="noopener noreferrer"&gt;https://tic-tac-j522t95x1-tejas-projects-d428ea49.vercel.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>tictoctoe</category>
      <category>gameusingjavascript</category>
      <category>javascript</category>
      <category>html</category>
    </item>
    <item>
      <title>RxJs: Does my observable gets unsubscribed if its source observable is unsubscribed?</title>
      <dc:creator>Tejas Naigaonkar</dc:creator>
      <pubDate>Tue, 24 Jun 2025 10:51:49 +0000</pubDate>
      <link>https://dev.to/jastya/rxjs-does-my-observable-gets-unsubscribed-if-its-source-observable-is-unsubscribed-1ngg</link>
      <guid>https://dev.to/jastya/rxjs-does-my-observable-gets-unsubscribed-if-its-source-observable-is-unsubscribed-1ngg</guid>
      <description>&lt;p&gt;I have subscribed to an observable - &lt;code&gt;MyObservable&lt;/code&gt;.&lt;br&gt;
Source observable of &lt;code&gt;MyObservable&lt;/code&gt; is &lt;code&gt;SourceObservable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question&lt;/strong&gt; - Does the subscription to &lt;code&gt;MyObservable&lt;/code&gt; is closed (unsubscribed) if the subscription to &lt;code&gt;SourceObservable&lt;/code&gt; is closed?&lt;/p&gt;

&lt;p&gt;Answer is &lt;u&gt;&lt;em&gt;Yes&lt;/em&gt;&lt;/u&gt;.&lt;/p&gt;

&lt;p&gt;Let's verify this with code.&lt;/p&gt;

&lt;p&gt;We'll create a method that returns an observable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const mySourceObservable = (): Observable&amp;lt;number&amp;gt; =&amp;gt;
  interval(2000).pipe(
    takeUntil(interval(5000)),
    map((val: number) =&amp;gt; val * 2)
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subscribe to the observable returned by above method and log the values emitted in the console&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const subscription = mySourceObservable().subscribe((val: number) =&amp;gt;
  console.log(val)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Code to check if the subscription is closed&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log(subscription);

setTimeout((_) =&amp;gt; console.log(subscription), 8000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the subscription to the source observable which is &lt;code&gt;interval(2000)&lt;/code&gt; is closed, the subscription to the observable returned by method &lt;code&gt;mySourceObservable()&lt;/code&gt; is also closed.&lt;/p&gt;

&lt;p&gt;Working solution with explanation using comments is available below, do check out - &lt;a href="https://stackblitz.com/edit/rxjs-playground-test-gxhfpsaf?file=index.ts" rel="noopener noreferrer"&gt;https://stackblitz.com/edit/rxjs-playground-test-gxhfpsaf?file=index.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this helps.&lt;/p&gt;

&lt;p&gt;Let me your thoughts.&lt;/p&gt;

&lt;p&gt;Best,&lt;br&gt;
Jastya!&lt;/p&gt;

</description>
      <category>rxjs</category>
      <category>observable</category>
      <category>subscription</category>
      <category>unsubscriber</category>
    </item>
  </channel>
</rss>
