error 'Stripe' is not defined no-undef - reactjs

I am trying to use the Stripe API to allow for payment through my website, but I am having issues adding Stripe into my project.
I used the create-react-app structure for my project, and added Stripe into the index.html file in /public/index.html as follows:
<body>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.39.0.min.js"></script>
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<script>
window.AWSCognito = window.AWS
</script>
<script src="https://gitcdn.xyz/repo/aws/amazon-cognito-identity-js/master/dist/amazon-cognito-identity.min.js"></script>
<div id="root"></div>
</body>
However when I test, I get an error:
/src/api/stripe.js
2:5 error 'Stripe' is not defined no-undef
My stripe.js file:
export const getStripeToken = (card) => new Promise((resolve, reject) => {
Stripe.card.createToken(card, (status, {error, id}) => {
if (error) {
reject(error.message);
} else {
resolve(id);
}
});
});
Thanks in advance!

I figured it out! I was being a bit of a dumby.
I changed Stripe to window.Stripe in my code, and it works now!
Thanks everyone.

It's only a problem of getting it compiled. The proper way to fix it is to ask compiler to not look for Stripe and it will be available globally. Add this comment /* global Stripe */ before you initialize Stripe:
/* global Stripe */
const stripe = Stripe('STRIPE_KEY');

Related

Next JS add async attribute for generates a list of script files

We are using nextJs application. We need to apply async for all existing script tags. I have tried a lot. any once can help me on this.
<script src="/_next/static/chunks/webpack.js?ts=1634913314210"></script>
<script src="/_next/static/chunks/main.js?ts=1634913314210"></script>
<script src="/_next/static/chunks/pages/_app.js?ts=1634913314210"></script>
after modification
<script src="/_next/static/chunks/webpack.js?ts=1634913314210" async></script>
<script src="/_next/static/chunks/main.js?ts=1634913314210" async></script>
<script src="/_next/static/chunks/pages/_app.js?ts=1634913314210" async></script>
If you are running NextJS v10.2.1 or newer, you can tell NextJS to render these resources with defer instead of async by setting the following flag in your next.config.js:
module.exports = {
experimental: { disableOptimizedLoading: true },
}
Note that this will only disable async tags for production builds, not development builds. Moreover, it also changes some other mechanisms related to script loading.
For more details, check out the implementation of _document.tsx getScripts, which exposes this method as a NextScript component. If you want to have more fine-grained control over these script tags, you can provide your own implementation of the getScripts method by implementing your own version of NextScript.
Below is an example I pulled from this relevant issue on the NextJS GitHub project. You may also want to read into that thread a little bit to better understand how async works in this context.
class DeferredNextScript extends NextScript {
getScripts() {
return super.getScripts().map(script => {
return React.cloneElement(script, {
key: script.props.src,
defer: true,
async: false,
})
})
}
getDynamicChunks() {
return super.getDynamicChunks().map(script => {
return React.cloneElement(script, {
key: script.props.src,
defer: true,
async: false,
})
})
}
}

`Uncaught ReferenceError: FB is not defined` in React

I have added Facebook login api into React app
// index.html
<body>
<div id="fb-root"></div>
<script src="https://connect.facebook.net..." etc... />
<script>
const FB = window.FB;
window.fbAsyncInit = function() {
FB.init({etc...});
FB.AppEvents.logPageView();
}
</script>
etc...
<div id="root"></div>
</body>
And then another one in the React provider
// SomeProvider.js
const SomeProvider = () => {
useEffect(() => {
window.FB.getLoginStatus((res) => {etc...});
}, []);
etc...
}
The error message I'm getting is that FB is not defined in SomeProvider.js and then another same message for react-dom.production.min.js.
I don't understand why.
Update
When I repeatedly refresh, sometimes that error doesn't appear, which makes me think that this is an asynchronous issue. It seems that window.FB.getLoginStatus needs to wait until FB.init in index.html is done. Am I correct with this assessment? Any recommendations regarding this?
you may try add [window.FB] as deps of useEffect of someprovide

How to integrate Tableau with React JS

I am working on React.js. I want to know how to integrate tableau with React JS code. If you have any reference let me know
Thanks for Advance
If you want to integrate your Tableau dashboard in your ReactJS application, you can either use the Tableau JavaScript API
Add this inside your Index.html : <script type="text/javascript" src="https://public.tableau.com/javascripts/api/tableau-2.min.js"></script>
and create one component to render the dashboard as per the instructions
here.
OR
use the Tableau-React library.
Add:
<script type="text/javascript" src="https://<tableauurl>/javascripts/api/tableau-2.min.js"></script>
then add:
const { tableau } = window;
const url = "https://<tableau-dashboard-url>/views/testing/map";
const ref = useRef(null)
console.log(ref);
function initViz(){
new tableau.Viz(ref.current, url);
}
useEffect(() => {
initViz();
},[])
And inside return, add below line:
<div ref={ref}></div>
It will work for sure :)

Adding Google Analytics to React

I am trying to add Google Analytics to a React Web Application.
I know how to do it in HTML/CSS/JS sites and I have integrated it in an AngularJS app too. But, I'm not quite sure how to go about it when it comes to react.
With HTML/CSS/JS, I had just added it to every single page.
What I had done with AngularJS was adding GTM and GA script to index.html and added UA-labels to the HTML divs (and buttons) to get clicks.
How can I do that with React?
Please help!
Update: Feb 2019
As I saw that this question is being searched a lot, I decided to expand my explanation.
To add Google Analytics to React, I recommend using React-GA.
Add by running:
npm install react-ga --save
Initialization:
In a root component, initialize by running:
import ReactGA from 'react-ga';
ReactGA.initialize('Your Unique ID');
To report page view:
ReactGA.pageview(window.location.pathname + window.location.search);
To report custom event:
ReactGA.event({
category: 'User',
action: 'Sent message'
});
More instructions can be found in the github repo
The best practice for this IMO is using react-ga.
Have a look at the github rep
If you prefer not to use a package this is how it can work in a react application.
Add the "gtag" in index.html
<!-- index.html -->
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "<GA-PROPERTYID>");
</script>
In the submit action of the login form, fire off the event
window.gtag("event", "login", {
event_category: "access",
event_label: "login"
});
Without using a package this is how I would do it:
In your index.js (in the render method):
{/* Global site tag (gtag.js) - Google Analytics */}
<script
async
src="https://www.googletagmanager.com/gtag/js?id=YOUR_TRACKING_ID"
/>
<script>{injectGA()}</script>
And outside the class:
const injectGA = () => {
if (typeof window == 'undefined') {
return;
}
window.dataLayer = window.dataLayer || [];
function gtag() {
window.dataLayer.push(arguments);
}
gtag('js', new Date());
gtag('config', 'YOUR_TRACKING_ID');
};
One other great library that you can check is redux-beacon.
It gets integrated very easily with react/redux application and has a great documentation for it. ReactGA is good too but with redux-beacon, you won't clutter your app code with google analytics code as it works via its own middleware.
Escape the analytics code with dangerouslySetInnerHTML
First you have of course to share the header code to all pages, e.g. as asked at: React js do common header
Then, this Next.js answer https://stackoverflow.com/a/24588369/895245 gives a good working code that should also work outside of Next.js. It escapes the analytics code with dangerouslySetInnerHTML:
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-47867706-3"></script>
<script
dangerouslySetInnerHTML={{
__html: `window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-47867706-3', { page_path: window.location.pathname });
`,
}}
/>
where you should replace UA-47867706-3 with your own code.
This code is exactly the code that Google gives, but with the following modification: we added the:
{ page_path: window.location.pathname }
to gtag('config' for it to be able to get the visited path, since this is a JavaScript SPA.
This generates the desired output on the browser:
<script async="" src="https://www.googletagmanager.com/gtag/js?id=UA-47867706-3"></script><script>window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-47867706-3', { page_path: window.location.pathname });
</script>
The only other divergence from the exact code given by Google is the async="" vs async, but both of those are equivalent in HTML since it is a boolean attribute, see also: What's the proper value for a checked attribute of an HTML checkbox?
Escaping with dangerouslySetInnerHTML is necessary because otherwise React interprets the code inside script a JSX and that fails with:
Syntax error: Unexpected token, expected "}"
21 | <script>
22 | window.dataLayer = window.dataLayer || [];
> 23 | function gtag(){dataLayer.push(arguments);}
| ^
24 | gtag('js', new Date());
25 |
26 | gtag('config', 'UA-47867706-3');
I wish they would just automatically escape stuff inside script for us.
Finally to get page switches, you also have to track that with more code, see the Next.js answer mentioned above for an example.
Related: Adding script tag to React/JSX
Tested on react 17.0.2, next.js 10.2.2.
There are 2 types of Google Analytics properties: Universal Analytics (UA-xxxxxxxxx-x) which is deprecated with the end of life on 2023.07.01 and Google Analytics 4 property (G-xxxxxxxxxx) which is the replacement.
react-ga was popular for Universal Analytics but the maintainer doesn't plan to update it (related issues: 1, 2, 3) and it had maintenance issues (1). react-ga4 and ga-4-react popped up as replacements but since these are similar wrappers you're at the mercy of the maintainers to implement and support all functionality.
The simplest way to get started is to follow Google's guide: include gtag on the page and use it as window.gtag. This method works for both old and new tags and there's even TypeScript support via #types/gtag.js. The script can be loaded async as recommended.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ... -->
<script
async
src="https://www.googletagmanager.com/gtag/js?id=G-xxxxxxxxxx" >
</script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-xxxxxxxxxx')
</script>
<!-- ... -->
</head>
<body>
<!-- ... -->
</body>
</html>
Keep in mind that Google Analytics does automatic page tracking, but this will not work for every use case. For example, hash and search parameter changes are not tracked. This can lead to a lot of confusion. For example, when using HashRouter or anchor links the navigation will not be tracked. To have full control over page view tracking you can disable automatic tracking. See for a detailed explanation: The Ultimate Guide to Google Analytics (UA & GA4) on React (Or Anything Else
Manual page tracking: https://stackoverflow.com/a/63249329/2771889
You can see this working in cra-typescript-starter where I'm also setting the tag from an env var.
I suggest embedding the Segment script into your index.html, use the analytics library that is accessible on the window object, and add tracking calls onto React’s event handlers:
export default class SignupButton extends Component {
trackEvent() {
window.analytics.track('User Signup');
}
render() {
return (
<button onClick={this.trackEvent}>
Signup with Segment today!
</button>
);
}
}
I’m the maintainer of https://github.com/segmentio/analytics-react. I recommend checking it out if you want to solve this problem by using one singular API to manage your customer data, and be able to integrate into any other analytics tool (we support over 250+ destinations) without writing any additional code. 🙂
Looking at google's site https://developers.google.com/analytics/devguides/collection/analyticsjs,
you could also add Google Analytics using this function:
const enableGA = () => {
!function(A,n,g,u,l,a,r){A.GoogleAnalyticsObject=l,A[l]=A[l]||function(){
(A[l].q=A[l].q||[]).push(arguments)},A[l].l=+new Date,a=n.createElement(g),
r=n.getElementsByTagName(g)[0],a.src=u,r.parentNode.insertBefore(a,r)
}(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X');
ga('send', 'pageview');
}
This way you don't need an external library, and it's pretty quick to setup.

Angularjs/Karma: Uncaught ReferenceError: inject is not defined

I got this service
angular.module('common.utils', [])
.service('Timer', function () {
function Timer() {
var start = new Date();
return function () {
return (new Date()).getTime() - start.getTime();
};
}
return Timer;
});
And i'm trying to write a simple test for it:
describe('common.utils', function() {
beforeEach(function () {
module('common.utils');
});
it('has a timer service', inject(function(Timer) {
expect(Timer).not.toBeNull();
}));
});
And I keep getting ReferenceError: inject is not defined.
I included angular.js, angular-mocks.js and all the app files (module is working... ). I don't understand what the problem is...
I had the same problem.
It turns out the issue was in the loading order of the files. You have to load jasmine before you load angular-mocks.
The following loading order will be throwing the error as mentioned in the question:
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/boot.js"></script>
<!-- include spec files here... -->
<script src="/spec/test.js"></script>
ReferenceError: inject is not defined
In several jasmine examples there is an additional comment included in the code:
<!-- include source files here... -->
The comment helps us to remind to load things in the right order.
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/jasmine-html.js"></script>
<script src="/bower_components/jasmine/lib/jasmine-core/boot.js"></script>
<!-- include source files here... -->
<script src="/bower_components/angular/angular.js"></script>
<script src="/bower_components/angular-mocks/angular-mocks.js"></script>
<!-- include spec files here... -->
<script src="/spec/test.js"></script>

Resources