Skip to content
This repository was archived by the owner on Jun 1, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"tsConfig": "tsconfig.app.json",
"allowedCommonJsDependencies": [
"@fnando/sparkline",
"fetch-jsonp",
"stream"
],
"assets": [
Expand Down
3 changes: 1 addition & 2 deletions docs/getting-started/troubleshooting.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Troubleshooting
## Troubleshooting

### `ngcc` Build Warnings (Angular >=8.0 && <16.0)
You might get warnings about SlickGrid while doing a production build, most of them are fine and the best way to fix them, is to simply remove/ignore the warnings, all you have to do is to add a file named `ngcc.config.js` in your project root (same location as the `angular.json` file) with the following content (you can also see this [commit](https://github.com/ghiscoding/angular-slickgrid-demos/commit/1fe8092bcd2e99ede5ab048f4a7ebe6254e4bee0) which fixes the Angular-Slickgrid-Demos prod build):
Expand Down Expand Up @@ -44,7 +44,6 @@ This is no longer the case. Verify if you need this module and configure a polyf
```ts
"options": {
"allowedCommonJsDependencies": [
"fetch-jsonp",
"stream"
],
},
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@
"eslint": "^9.16.0",
"eslint-plugin-cypress": "^4.1.0",
"eslint-plugin-n": "^17.14.0",
"fetch-jsonp": "^1.3.0",
"jest": "^29.7.0",
"jest-extended": "^4.0.2",
"jest-preset-angular": "^14.4.1",
Expand Down
31 changes: 23 additions & 8 deletions src/app/examples/grid-editor.component.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { TranslateService } from '@ngx-translate/core';
import fetchJsonp from 'fetch-jsonp';

import {
AngularGridInstance,
AutocompleterOption,
Expand All @@ -27,6 +25,8 @@ import { CustomInputEditor } from './custom-inputEditor';
import { CustomInputFilter } from './custom-inputFilter';
import { Subject } from 'rxjs';

import fetchJsonp from './jsonp';

const NB_ITEMS = 100;
const URL_SAMPLE_COLLECTION_DATA = 'assets/data/collection_100_numbers.json';
const URL_COUNTRIES_COLLECTION = 'assets/data/countries.json';
Expand Down Expand Up @@ -338,11 +338,26 @@ export class GridEditorComponent implements OnInit {
/** with Angular Http, note this demo won't work because of CORS */
// this.http.get(`http://gd.geobytes.com/AutoCompleteCity?q=${searchText}`).subscribe(data => updateCallback(data));

/** with JSONP AJAX will work locally but not on the GitHub demo because of CORS */
fetchJsonp(`http://gd.geobytes.com/AutoCompleteCity?q=${searchText}`)
.then((response) => response.json())
.then((json) => updateCallback(json))
.catch((ex) => console.log('invalid JSONP response', ex));
const clearFunction = (functionName: string) => {
delete (window as any)[functionName];
}
const processJSONPResponse = (data: any) => {
updateCallback(data);
clearFunction('processJSONPResponse');
}

(window as any).processJSONPResponse = processJSONPResponse;
const script = document.createElement('script');
script.src = `http://gd.geobytes.com/AutoCompleteCity?q=${searchText}&callback=processJSONPResponse`
document.getElementsByTagName('head')[0].appendChild(script);

// fetchJsonp<string[]>(`http://gd.geobytes.com/AutoCompleteCity?q=${searchText}`, { crossorigin: true })
// .then((response) => {

// return response.json()
// })
// .then((json) => updateCallback(json))
// .catch((ex) => console.log('invalid JSONP response', ex));
},
} as AutocompleterOption,
},
Expand All @@ -358,7 +373,7 @@ export class GridEditorComponent implements OnInit {
filterOptions: {
minLength: 3,
fetch: (searchText: string, updateCallback: (items: false | any[]) => void) => {
fetchJsonp(`http://gd.geobytes.com/AutoCompleteCity?q=${searchText}`)
fetchJsonp<string[]>(`http://gd.geobytes.com/AutoCompleteCity?q=${searchText}`, { crossorigin: true })
.then((response) => response.json())
.then((json) => updateCallback(json))
.catch((ex) => console.log('invalid JSONP response', ex));
Expand Down
1 change: 0 additions & 1 deletion src/app/examples/grid-remote.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// import fetchJsonp from 'fetch-jsonp';
// import 'slickgrid/slick.remotemodel'; // SlickGrid Remote Plugin

import { Component, OnInit, OnDestroy } from '@angular/core';
Expand Down
89 changes: 89 additions & 0 deletions src/app/examples/jsonp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* copied and rewritten as ESM (just a simple rewrite as ESM to avoid loading a CJS package)
* https://github.com/camsong/fetch-jsonp/blob/master/src/fetch-jsonp.js
*/

interface JsonpOptions {
timeout: number;
jsonpCallback: string;
jsonpCallbackFunction: string;
charset: string;
nonce: string;
referrerPolicy: string;
crossorigin: boolean;
};

const defaultOptions = {
timeout: 5000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null,
};
const generateCallbackFunction = () => `jsonp_${Date.now()}_${Math.ceil(Math.random() * 100000)}`;
const clearFunction = (functionName: string) => delete (window as any)[functionName];
const removeScript = (scriptId: string) => {
const script = document.getElementById(scriptId);
if (script) {
document.getElementsByTagName('head')[0].removeChild(script);
}
};

function fetchJsonp<T = any>(_url: string, options: Partial<JsonpOptions> = {}): Promise<{ ok: boolean; json: () => Promise<T>; }> {
// to avoid param reassign
let url = _url;
const timeout = options.timeout || defaultOptions.timeout;
const jsonpCallback = options.jsonpCallback || defaultOptions.jsonpCallback;
let timeoutId: any;

return new Promise((resolve, reject) => {
const callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
const scriptId = `${jsonpCallback}_${callbackFunction}`;

(window as any)[callbackFunction] = (response: T) => {
// keep consistent with fetch API
resolve({ ok: true, json: () => Promise.resolve(response) });
if (timeoutId) clearTimeout(timeoutId);
removeScript(scriptId);
clearFunction(callbackFunction);
};

// Check if the user set their own params, and if not add a ? to start a list of params
url += (url.indexOf('?') === -1) ? '?' : '&';

const jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', `${url}${jsonpCallback}=${callbackFunction}`);
if (options.charset) {
jsonpScript.setAttribute('charset', options.charset);
}
if (options.nonce) {
jsonpScript.setAttribute('nonce', options.nonce);
}
if (options.referrerPolicy) {
jsonpScript.setAttribute('referrerPolicy', options.referrerPolicy);
}
if (options.crossorigin) {
jsonpScript.setAttribute('crossorigin', 'true');
}
jsonpScript.id = scriptId;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);

timeoutId = setTimeout(() => {
reject(new Error(`JSONP request to ${_url} timed out`));

clearFunction(callbackFunction);
removeScript(scriptId);
(window as any)[callbackFunction] = () => {
clearFunction(callbackFunction);
};
}, timeout);

// Caught if got 404/500
jsonpScript.onerror = () => {
reject(new Error(`JSONP request to ${_url} failed`));
clearFunction(callbackFunction);
removeScript(scriptId);
if (timeoutId) clearTimeout(timeoutId);
};
});
}

export default fetchJsonp;
5 changes: 0 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6017,11 +6017,6 @@ fd-slicer@~1.1.0:
dependencies:
pend "~1.2.0"

fetch-jsonp@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/fetch-jsonp/-/fetch-jsonp-1.3.0.tgz#99b8c25bd100938d7a7a6b5db9d6b81f32a10809"
integrity sha512-hxCYGvmANEmpkHpeWY8Kawfa5Z1t2csTpIClIDG/0S92eALWHRU1RnGaj86Tf5Cc0QF+afSa4SQ4pFB2rFM5QA==

fflate@^0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea"
Expand Down
Loading