Running an external JavaScript code in ReactJs - reactjs

I want to run an external JS which is actually opencv.js. I need to access its CV variable and then calling other functions.
I am adding below codes to my useeffect hook as follow:
export default function PolygonCropper(props) {
...
useEffect(() => {
const script = document.createElement("script");
script.src = "https://docs.opencv.org/3.4.0/opencv.js";
script.async = false;
document.body.appendChild(script);
//
console.log('cv from opencv is');
console.log(window["cv"]);
....
}
However, I can't access window["cv"] and it is undefined when I look at logs in chrome.
EDIT:
looking at Chrome log by console.log(window). I can see the window and CV inside it but I can access window["cv"]

Related

How to use ethers.js-JsonRpcProvider with Next.js to retrieve onchain data?

I'm trying to read some on-chain data with ethers.js JsonRpcProvider. I'm calling it with an Alchemy key, stored in a .env file.
edit : Making this variable only visible to server side is intentionnal, because I do not want to share this "sensible" information. Maybe it's not the right way to do this, I don't know...
I can't load my data on the client side, but on the server side, everything seems fine :/
What I'm doing wrong?
// ALCHEMY_API_KEY_URL is in .env file
const passiveProvider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_API_KEY_URL)
// everything's fine on server side
console.log(passiveProvider)
const whiteListContract = new ethers.Contract(WHITELIST_CONTRACT_ADDRESS, abi, passiveProvider)
export default function Home() {
const [value, setValue] = React.useState("")
React.useEffect(() => {
async function getNumAddressesWhitelisted(contract) {
try {
// we're in useEffect, client-side, nothing works here :/
// dunno if this executes
const clientTx = await contract.numAddressesWhitelisted()
console.log("numAddressesWhitelisted : ", clientTx)
setValue(clientTx)
} catch (err) {
// we drop here each time
console.log("there is an error ! ",err)
// error message dropped :
// there is an error ! Error: could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.7.0)
// at Logger.makeError (index.js?dd68:224:1)
// at Logger.throwError (index.js?dd68:233:1)
// at JsonRpcProvider.eval (json-rpc-provider.js?8679:442:1)
// at Generator.throw (<anonymous>)
// at rejected (json-rpc-provider.js?8679:6:42)
}
}
getNumAddressesWhitelisted(whiteListContract)
}, [])
return (
<div>
{value}
</div>
)
}
I think this line with the env variable is the issue:
const passiveProvider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_API_KEY_URL)
Because environment variables that are inside .env file loaded on the server but not on the client. so passiveProvider is successfully defined on server side but client-side. In order to that env variable work on the client side, you have to add NEXT_PUBLIC_ prefix to the naming
NEXT_PUBLIC_ALCHEMY_API_KEY_URL=...........
now this env variable will be defined on the client side
const passiveProvider = new ethers.providers.JsonRpcProvider(process.env.NEXT_PUBLIC_ALCHEMY_API_KEY_URL)
What's the difference between exposing environment variables in nextjs through the next.config.js vs with the NEXT_PUBLIC prefix?
Ok, I think I've figured out a righter/cleaner way to do this by far :
I needed getServerSideProps. getServerSideProps can only exist in a next.js page, executes code on server side only, and returns props passed to the page.
The logs appears only on server side too, as expected :
export async function getServerSideProps() {
// ALCHEMY_API_KEY_URL is defined in .env file, it's visible only from server side
const passiveProvider = new ethers.providers.JsonRpcProvider(process.env.ALCHEMY_API_KEY_URL)
console.log("passive provider : ", passiveProvider)
const whiteListContract = new ethers.Contract(WHITELIST_CONTRACT_ADDRESS, abi, passiveProvider)
const clientTx = await whiteListContract.numAddressesWhitelisted()
console.log("numAddressesWhitelisted : ", clientTx)
return { props: { clientTx } }
}
export default function Home({ clientTx }) {
return (
<div>
{clientTx}
</div>
)
}

ui cant find the js loaded under a different space

This is the code I used to load the external js transaction-element
addTransactionElement() {
this.http.get<any>('../transaction/transactionUrl').subscribe((res) => {
const link = this.renderer.createElement('link');
link.rel = 'stylesheet';
link.href = 'http://localhost:8083/elements/assets/fonts/webadk-icon-font.css';
this.renderer.appendChild(this.document.head, link);
const script = this.renderer.createElement('script');
script.type = 'text/javascript';
this.renderer.setAttribute(script, 'crossorigin', 'true');
script.src = 'http://localhost:8083/transaction-element.js';
script.text = ``;
this.renderer.appendChild(this.document.head, script);
});
}
I can see it loaded though under a different space, localhost:8083, where the element.js is hosted. My own ui space is hosted under localhost:4200.
This is code to render it.
<transaction-element
businessLine="{{ transactionInfo.businessLine }}"
theme="{{ transactionTheme }}"
></transaction-element>
It does not happen. No error messages anywhere. Is it because the external element.js is uploaded under a different space? If so, anyway to correct it?
Thanks

React how to inject js dependency at runtime

So need to following dependency in my application:
<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY></script>
Problem is I don't have my key until runtime. I am not sure what the "react" way of injecting this at runtime would be? I realize i could get the head element and add the html in the window onload event like below:
document.head.append('<script src="https://maps.googleapis.com/maps/api/js?key=API_KEY></script>');
Is this the best way to do this?
have you tried to add on your componentDidMount or useEffect?
componentDidMount() {
const script = document.createElement('script');
const key = <GET_YOUR_API_KEY>
script.type = 'text/javascript';
script.src = `https://maps.google.com/maps/api/js?key=${key}`;
script.id = 'someID';
document.body.appendChild(script);
script.addEventListener('load',() => console.log('map loaded'))
}

Amazon Native Shopping Ads (Search Ads) in React

https://affiliate-program.amazon.com/welcome/getstarted_fifth
Is it possible to introduce Amazon Native Shopping Ads' 「Search Ads 」 into the React project?
I attempted trial and error, but I do not think that it is probably going well with global variable issues.
Here is how I did it.
If your Native Shopping Ads code looks like this:
<div id="amzn-assoc-ad-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></div><script async src="//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US&adInstanceId=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"></script>
In your component,
componentDidMount () {
const script = document.createElement("script");
script.src = "//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US&adInstanceId=xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx";
script.async = true;
document.body.appendChild(script);
}
In your JSX
<div id="amzn-assoc-ad-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"> </div>
Yes it works very well with this logic but I made a better version out of it.
In your React Hook
useEffect(() => {
const script = document.createElement('script')
script.text = `amzn_assoc_ad_type = "banner"; amzn_assoc_marketplace = "amazon"; amzn_assoc_region = "US"; amzn_assoc_placement =
"assoc_banner_placement_default"; .................`
const script2 = document.createElement('script')
script2.src = '//z-na.amazon-adsystem.com............'
script2.async = false
const amazonAdd = document.querySelector('#amzn_assoc_ad_div_assoc_banner_placement_default_0')
if (amazonAdd) {
amazonAdd.appendChild(script)
amazonAdd.appendChild(script2)
}
}, [])
In your JSX
<div id="amzn_assoc_ad_div_assoc_banner_placement_default_0" />
You need to use the exact same id than amazon uses. Take a look in your DOM to see how this amazon script append a div in your DOM, get its id and use the same in your JSX div

Add google trends in react

How do you add components such as charts in google trends in reactjs?
componentDidUpdate() {
const that = this
const keyword = "your keyword"
conts script = document.createElement("script")
script.src = "https://ssl.gstatic.com/trends_nrtr/760_RC08/embed_loader.js"
script.async = true
ReactDOM.findDOMNode(this.refs.trendsWrapper1).appendChild(script)
script.onload = function () {
trends.embed.renderExploreWidgetTo(ReactDOM.findDOMNode(that.refs.trendsWrapper1), "TIMESERIES", {"comparisonItem":[{"keyword":keyword,"geo":"","time":"today 5-y"}],"category":0,"property":""}, {"exploreQuery":"q=%2Fm%2F0rfgxy2","guestPath":"https://www.google.co.uk:443/trends/embed/"})
}
}
I tried this and didn't work. Please try to suggest a much easier method than this as well.
You need to load the embed_loader script out side of react (like any other 3rd lib code)
At the component, run the trends.embed command.
var Trends = React.createClass({
render: function() {
trends.embed.renderWidget("US_cu_mqCQGFwBAABWOM_en",
"fe_line_chart_309e703b-7d68-4baa-8dc9-c12e2f9defc3",
{"guestPath":"https://trends.google.com:443/trends/embed/"});
return (
<div>must return something :/</div>
)}
});
Here is an example

Resources