Adyen's Checkout SDK integration in react app - javascript

I have a react app and I want to set up adyen (payment processing API) in that. I want to use the checkout SDK (https://docs.adyen.com/developers/checkout/web-sdk )as its very simple,
I have moved the js logic to componentDidMount, but having problem loading the sdk,
<script type="text/javascript" src="https://checkoutshopper-test.adyen.com/checkoutshopper/assets/js/sdk/checkoutSDK.1.6.3.min.js"></script>
So I can use the below function from SDK:
chckt.hooks.beforeComplete = function(node, paymentData) {
return false; // Indicates that you want to replace the default handling.
};
I have tried using react-script-tag, in my React component:
render() {
return (
<div className='checkout-warpper'>
<ScriptTag type="text/javascript" src="https://checkoutshopper-test.adyen.com/checkoutshopper/assets/js/sdk/checkoutSDK.1.9.2.min.js" />
<div className="checkout" id="adyen-checkout">
{/* The checkout interface will be rendered here */}
</div>
</div>
);
}
but still get the error:
Uncaught ReferenceError: chckt is not defined.

Try window.chckt.hooks.beforeComplete = ... chckt is a global scope variable.
The easiest way to load external script is by using react-async-script-loader
import React from 'react';
import scriptLoader from 'react-async-script-loader'
class CheckoutSDK extends React.Component {
componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
if (isScriptLoaded && !this.props.isScriptLoaded) { // load finished
if (isScriptLoadSucceed) {
window.chckt.hooks.beforeComplete = function(node, paymentData) {
return false; // Indicates that you want to replace the default handling.
};
}
}
}
render() {
return null
}
}
export default scriptLoader('https://checkoutshopper-test.adyen.com/checkoutshopper/assets/js/sdk/checkoutSDK.1.6.3.min.js',)(CheckoutSDK)

you can try using import ScriptLoader from 'react-script-loader-hoc'; and you can find on window.chckt.

Related

How To Use VdoCipher with React js

How to fetch videos from VdoCipher and display then on my React js WebApp?
I am currently trying to use VdoCipher to store videos (I will upload them manually on the website) and then display them on my react webapp... infortuntly the documentation isn't very clear for me.
Here is some sample code to implement this
import React, { Component } from "react";
import "./style.css";
class VideoPlayer extends Component {
constructor(props) {
super(props);
this.state = {
videoObject: null
};
}
componentDidMount() {
if (window.VdoPlayer) {
return this.loadPlayer();
}
const playerScript = document.createElement("script");
playerScript.src =
"https://player.vdocipher.com/playerAssets/1.6.10/vdo.js";
document.body.appendChild(playerScript);
playerScript.addEventListener("load", () => {
return this.loadPlayer();
});
}
loadPlayer() {
window.playerContainer = this.refs.container;
new window.VdoPlayer({
otp: this.props.otp,
playbackInfo: this.props.playbackInfo,
theme: "9ae8bbe8dd964ddc9bdb932cca1cb59a",
container: this.refs.container
});
}
render() {
return <div className="player" ref="container"></div>;
}
}
export default VideoPlayer;
Codesandbox link for working version
Since there is a javascript src to be loaded, it checks in componentDidMount for the presence of global variable. You can choose to use this by alternative means such as scriptjs or adding script tag the index.html template.
The return of the new VdoPlayer() is supposed to be the reference of player that you need to call javascript APIs on player. If needed, you can make it available to the outside components with a callback prop. And then call this callback prop after the new VdoPlayer()

Load function from external script using #loadable/component in React

I have a JSON file with several filepaths to scripts that I want to be able to load dynamically into my React app, to build each component based on specifications that are in the metadata. Currently I have the metadata in my app as a Metadata data object.
metadata.json:
{
"component1": { "script": "./createFirstLayer.js" },
"component2": { "script": "./createSecondLayer.js" }
}
Each script exports a function that I want to be able to use to construct the component. For troubleshooting purposes, it currently only returns a simple message.
function createFirstLayer(name) {
return name + " loaded!";
}
export default createFirstLayer;
I did some research and identified the #loadable/component package. Using this package as import loadable from "#loadable/component";, I attempted to load my script into App.js like this:
async componentDidMount() {
Object.keys(Metadata).forEach(function(name) {
console.log(Metadata[name].script);
var createLayer = loadable(() => import(Metadata[name].script));
var message = createLayer(name);
console.log(message);
});
}
Everything I have tried throws the TypeError createLayer is not a function. How can I get the function loaded?
I have also attempted the lazy method.
I have recreated a working demo of my problem here.
EDIT: I have tried to put this at the top of my app
const scripts = {};
Object.keys(Metadata).forEach(async function(name) {
import(Metadata[name].script).then((cb) => scripts[name] = cb);
});
This causes the TypeError Unhandled Rejection (Error): Cannot find module './createFirstLayer.js'. (anonymous function)
src/components lazy /^.*$/ groupOptions: {} namespace object:66
I have also attempted
const scripts = {};
Object.keys(Metadata).forEach(async function(name) {
React.lazy(() => import(Metadata[name].script).then((cb) => scripts[name] = cb));
});
My goal is to be able to call the appropriate function to create particular layer, and match them up in the metadata.
You don't need #loadable/component for two reasons.
You can accomplish your goal with dynamic imports
'#loadable/component' returns a React Component object, not your function.
To use dynamic imports simply parse your JSON the way you were, but push the call to the import's default function into state. Then all you have to do is render the "layers" from within the state.
Like this:
import React, { Component } from "react";
import Metadata from "./metadata.json";
class App extends Component {
constructor(props) {
super(props);
this.state = { messages: [] };
}
async componentDidMount() {
Object.keys(Metadata).forEach(name=> import(`${Metadata[name].script}`).then(cb =>
this.setState((state, props) => ({ messages: [...state.messages, cb.default(cb.default.name)] }))));
}
render() {
return (
<div className="App">
{this.state.messages.map((m, idx) => (
<h1 key={idx}>{m}</h1>
))}
</div>
);
}
}
export default App;
Here is the working example

React doesn't recognize function

I am trying this tutorial for the react chat and keep getting the error
TypeError: n.props.handleNewUserMessage is not a function
I tried to resolve it using the following resources:
https://www.reddit.com/r/reactjs/comments/6fd6nl/keep_getting_error_thispropsonsearch_in_not_a/?st=jhiugk4d&sh=fabd3cc4
ReactJS with ES6: this.props is not a function when I communicate two components
React TypeError this._test is not a function
React does not recognize my function
This is my code:
import React, { Component } from 'react';
import { Widget, addResponseMessage } from 'react-chat-widget';
import 'react-chat-widget/lib/styles.css';
class App extends Component {
componentDidMount() {
addResponseMessage("How can I help you?");
}
handleNewUserMessage = (newMessage) => {
console.log(`New message incomig! ${newMessage}`);
// Now send the message throught the backend API
addResponseMessage('response');
}
render() {
return (
<div className="App">
<Widget />
</div>
);
}
}
export default App;
Where have I gone wrong?
Just as the error mentions, you forgot to actually add the method to the props:
<Widget
handleNewUserMessage={this.handleNewUserMessage}
/>

How do I embed a facebook send button in my react app?

I have a client side rendered react app. I want to display a facebook send button on my page.
The instructions given on the developer page do not tell me how to do it
https://developers.facebook.com/docs/plugins/send-button#configurator
Plus, I did not find an npm compatible package released by facebook for their SDK. So how does one go about including the SDK in a react app?
EDIT: I tried using some async loader in react.
import React, { Component } from 'react';
import scriptLoader from 'react-async-script-loader';
#scriptLoader(
'https://connect.facebook.net/es_ES/sdk.js#xfbml=1&version=v2.5',
)
class FacebookSendButton extends Component {
componentDidMount() {
const { isScriptLoaded, isScriptLoadSucceed } = this.props;
if (isScriptLoaded && isScriptLoadSucceed) {
console.log('script load success from didMount');
}
}
componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
if (isScriptLoaded && !this.props.isScriptLoaded) { // load finished
if (isScriptLoadSucceed) {
console.log('script load success from receiveProps');
}
}
}
render() {
return (
<div>
BEFORE FB ROOT.
<div className="fb-send"
dataHref="http://www.your-domain.com/your-page.html"
dataLt ayout="button_count"
/>
<div id="fb-root"></div>
</div>
);
}
}
export default FacebookSendButton;
This does not render a facebook send button.
Once the FB SDK loads, it parses through the entire markup of the page to find elements with the special fb-* classes. Since the FB script is loading at the time your module is initialized, it's likely that the SDK loads before you end up mounting your component. To get it to re-process the DOM, you'd want to add something like the following to your componentDidMount:
if (window.FB) {
// Read the entire document for `fb-*` classnames
FB.XFBML.parse();
}
Of course, you probably don't want to parse the entire document every time a send button mounts. You can narrow the scope of the search by creating a ref to the DOM node you want to search, and then passing that to the parse() method.
componentDidMount() {
const { isScriptLoaded, isScriptLoadSucceed } = this.props;
if (isScriptLoaded && isScriptLoadSucceed && window.FB) {
window.FB.XFBML.parse(this._scope);
}
}
componentWillReceiveProps({ isScriptLoaded, isScriptLoadSucceed }) {
if (isScriptLoaded && !this.props.isScriptLoaded) { // load finished
if (isScriptLoadSucceed && window.FB) {
window.FB.XFBML.parse(this._scope);
}
}
}
render() {
return (
<div ref={(s) => this._scope = s}>
<div id="fb-root"></div>
<div
className="fb-send"
data-href="http://www.your-domain.com/your-page.html"
data-layout="button_count"
/>
</div>
);
}
You'll notice I use the new method of functional refs here. Named refs (eg ref="somestr") are being deprecated & discouraged by the React team.
I have a hacky version of this working from the following gist: https://gist.github.com/andrewimm/9fdd0007c3476446986a9f600ba4183f

this.getDomNode() in reapp returns undefined

I just got started with reapp. I simply created an app. Once the app was created, I modified the default home.jsx as shown:
import { Reapp, React } from 'reapp-kit';
class Home extends React.Component {
render() {
return (
<div className='map'></div>
);
}
getDefaultProps() {
return {
initialZoom: 8,
mapCenterLat: 43.6425569,
mapCenterLng: -79.4073126,
};
}
componentDidMount() {
console.log('Dom node is ',this.getDomNode());
}
}
export default Reapp(Home);
Now the issue is the this.getDomNode which returns the error
Uncaught TypeError: undefined is not a function
Does anyone have any idea what might be wrong ??
You should use React.findDOMNode(this) instead of this.getDOMNode(), which is deprecated in 0.13.0 and isn't available on classes that extend React.Component.
You should use React.findDOMNode(this) instead of getDomNode,
class Home extends React.Component {
render() {
return (
<div className='map'></div>
);
}
componentDidMount() {
console.log('Dom node is ', React.findDOMNode(this));
}
}
Those who are looking for the updated answer for the latest React, here it goes.
React findDOMNode API is been moved into a react-dom package. You can find the reference here.
So use,
import ReactDOM from "react-dom";
ReactDOM.findDOMNode(component)
to get the element.
Thank you.

Categories

Resources