Tips on integrating Cheerio with Angular framework

My Angular website is encountering errors in Google Dev Tools's console when I utilize a Cheerio method

load('<h2 class="title">Hello world</h2>');
as per the instructions on the Github page.

This application is fresh, and the steps I took are as follows: sudo ng new myProject, sudo chmod -R 777 myProject/, sudo npm install cheerio --save,

sudo npm install @types/cheerio --save
. To preempt any TypeScript compilation errors that may arise, I also executed: sudo npm install stream --save

In my app.component.ts file, I imported Cheerio using

import * as cheerio from 'cheerio';
and within the component itself:

ngOnInit() {
  cheerio.load('<h2 class="title">Hello world</h2>');
}

Upon running ng serve, the specific error message displayed is:

inherits_browser.js:5 Uncaught TypeError: Cannot read property 'prototype' of undefined
    at inherits (inherits_browser.js:5)
    at Object../node_modules/cheerio/node_modules/parse5/lib/parser/parser_stream.js (parser_stream.js:27)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/node_modules/parse5/lib/index.js (index.js:41)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/lib/parse.js (parse.js:5)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/lib/cheerio.js (cheerio.js:5)
    at __webpack_require__ (bootstrap:78)
    at Object../node_modules/cheerio/index.js (index.js:5)
inherits @ inherits_browser.js:5
./node_modules/cheerio/node_modules/parse5/lib/parser/parser_stream.js @ parser_stream.js:27
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/node_modules/parse5/lib/index.js @ index.js:41
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/lib/parse.js @ parse.js:5
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/lib/cheerio.js @ cheerio.js:5
__webpack_require__ @ bootstrap:78
./node_modules/cheerio/index.js @ index.js:5
__webpack_require__ @ bootstrap:78
./src/app/app.component.ts @ main.js:94
__webpack_require__ @ bootstrap:78
./src/app/app.module.ts @ app.component.ts:10
__webpack_require__ @ bootstrap:78
./src/main.ts @ main.ts:1
__webpack_require__ @ bootstrap:78
0 @ main.ts:12
__webpack_require__ @ bootstrap:78
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.js:1

Furthermore, attempting to fix the issue by placing import { load } from 'cheerio'; at the top of the file has not resolved the error.

The versions of my tools are as follows (all latest or close to it): Angular CLI: 7.3.6 Node: 11.12.0 OS: darwin x64 Angular: 7.2.11

Edit: Following the solution provided in Adding Cheerio.js to an Angular 6 project? did not rectify the issue; instead, it introduced another error in the console:

cheerio.js:5 Uncaught ReferenceError: require is not defined
    at cheerio.js:5

Answer №1

When attempting to integrate cheerio with Angular, simply adding the package was not sufficient. The hurdle I faced was due to missing NodeJS dependencies that cheerio relies on, which are not inherently available in the browser environment.

To resolve this issue, I needed to include additional packages, modify the "polyfill.ts" file, and adjust the "tsconfig.json" configuration.

Here's how I tackled the problem:

Initially, I installed the following npm packages:

  • stream-browserify
  • string_decoder
  • events
  • buffer
  • process

One simple command to install these packages:

npm install stream-browserify string_decoder events buffer process

It's worth noting that not all of these packages may be necessary for your specific use case.

Next, I made modifications to the "polyfill.ts" file as follows:

// Emulating nodejs imports for cheerio
import * as process from 'process';
window['process'] = process;

(window as any).global = window;
var global = global || window;

import * as bufferModule from "buffer"
global.Buffer = global.Buffer || bufferModule.Buffer;

This solution is a combination of insights gleaned from similar issues and questions I came across during my research.

Lastly, I configured a path in the "tsconfig.json" file to map the stream module to the stream-browserify package located in the node-modules directory, as detailed in this answer:

tsconfig.json:

{
  "compilerOptions": {
    "paths": {
      "stream": [
        "node_modules/stream-browserify"
      ]
    }
  }
}

I made these adjustments to the "tsconfig.json" file in the root directory, alongside the "package.json" file.

Additional Notes and Insights:

Related Issues to Explore:

Answer №2

I have yet to explore the wonders of the cheerio library. However, I took the initiative to create a live demo on StackBlitz to demonstrate how it can be utilized.

For this project, I had to utilize npm to install the necessary packages by running the command:

npm install cheerio @types/cheerio events string_decoder

In the app.component.ts file, I proceeded to import cheerio using:

import * as cheerio from 'cheerio';
and implemented it within the ngOnInit method like this:
cheerio.load('<h2 class="title">Hello world</h2>').xml();

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Type the query into the search bar on the website, hit the submit button, and receive the search results

Is there a way to dynamically pass any query string (from any oracle table, not hardcoded) from a webpage form/field to the database and have the webpage display a table/grid of the results without predefining columns or table names? Current examples I&apo ...

Leveraging the outcome of an Observable in one method with another Observable in Angular2

The issue at hand I am facing difficulty in utilizing the value returned by the Observable from getUserHeaders() within my http.get request. Error encountered Type 'Observable<void>' is not assignable to type 'Observable<Particip ...

Retrieving Headers from a POST Response

Currently, I am utilizing http.post to make a call to a .NET Core Web API. One issue I am facing is the need to extract a specific header value from the HTTP response object - specifically, the bearer token. Is there a method that allows me to achieve thi ...

Forcing locale in Angular 2: A step-by-step guide

I recently developed a compact application with Angular2 and incorporated the currency pipe. I noticed that the currency is automatically formatted based on my browser's language. Is there a way for me to customize or override this default behavior? ...

The compatibility issue arises when using Material UI Portal with TypeScript, specifically with the 'children' property types

When rendering a component using Material-UI Portal that includes several Material UI buttons, the following code is used: <Portal container={this.myContainer}> <Button onClick={this.handleClick}>Do something</Button> //other but ...

connect the validation of forms to different components

I am currently working on components to facilitate the user addition process. Below is an example of my form component: createForm(): void { this.courseAddForm = this.formBuilder.group({ name: ['', [ Validators.required, ...

Creating dynamic HTML templates in Webstorm using template strings with Angular 2

As mentioned in the release notes for WebStorm 2016.1, there is an image displayed. https://i.sstatic.net/9h1Yg.png Check this out here However, when I try to replicate it, mine ends up looking like this https://i.sstatic.net/ScP8W.png Do I need to ma ...

Why does the server attempt to load the chart in Angular 10 Universal using Amcharts 4?

I have experience with Angular, but I am now delving into the world of using Universal for SEO purposes. My goal is to integrate a map from amcharts 4, which works fine without Angular Universal. However, I am facing an issue where the server attempts to ...

Trouble arises when applying CSS to ng-x accordion styling

While working with ng-x accordion in Angular 2, I successfully rendered my accordion component. However, I encountered an issue when trying to add styles to the template provided by ng-x accordion. Despite using CSS in my rendered component for classes l ...

Enhance your Typescript code with a type guard that supports optional wrapped types

I haven't come across a question similar to this one before. My goal is to develop a type guard that can accurately determine the type of a specific variable. It's quite simple with a single type. type A = { id: number, title: string, type: stri ...

Neglecting the error message for type assignment in the Typescript compiler

Presented here is a scenario I am facing: const customer = new Customer(); let customerViewModel = new CustomerLayoutViewModel(); customerViewModel = customer; Despite both Customer and CustomerLayoutViewModel being identical at the moment, there is no ...

Step-by-step guide on deploying Angular Universal

Exploring Angular universal and working on understanding deployment strategies. Check out the Github repository at https://github.com/angular/universal-starter This project includes Angular 2 Universal, TypeScript 2, and Webpack 2. After running the comm ...

Experiencing problems with React createContext in Typescript?

I've encountered a strange issue with React Context and Typescript that I can't seem to figure out. Check out the working example here In the provided example, everything seems to be working as intended with managing state using the useContext ...

Angular 14 troubleshooting: Issues with using getRawValue() in IndexOf function

In this scenario, I have a straightforward Person interface defined as: import { FormArray, FormControl, FormGroup } from '@angular/forms'; import { Address } from './address'; export class Person { id: FormControl<number>; n ...

I am looking to extract only the alphanumeric string that represents the Id from a MongoDB query

Working with mongoDB, mongoose, and typescript, I am facing an issue where I need to preserve the document ids when querying. However, all I can retrieve is the type _id: new ObjectId("62aa4bddae588fb13e8df552"). What I really require is just the string ...

What is the purpose of RouterLink and RouterOutlet in Angular?

RouterLink and RouterOutlet are both angular attribute directives that assist in navigating to a specific route from the collection of routes. Once a matching route is found, the corresponding component is loaded, and its template is rendered on the browse ...

How can I utilize npm with the original source code instead of minified or bundled code?

I am looking to access npm and JavaScript (or TypeScript) 3rd party libraries directly from the source code. Similar to how I can make changes in Python libraries by going into their source code, I want to have the same capability with my JavaScript depen ...

Angular 2: Implementing service functions on button click using the (click) event

Is it possible to call a function from my service when clicking on an element in the HTML returned from an HTTP call? Here is the HTML snippet: <a (click)="SellingVarietiesService.goToVarietyDetails(3)">Test</a> The function I want to call i ...

Sign out from Azure Active Directory using the ADAL library in an Angular application written in TypeScript

When navigating multiple tabs in a browser, I am encountering an issue with logging out using adal. How can I successfully log out from one tab while still being able to use another tab without any hindrance? Currently, when I log out from one tab, it pr ...

Utilizing Mongoose Schema Enums Alongside TypeScript Enums

In our Typescript-based NodeJs project utilizing Mongoose, we are seeking the right approach to define an enum field on a Mongoose schema that aligns with a Typescript enum. To illustrate, consider the following enum: enum StatusType { Approved = 1, ...