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
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>
)
}
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
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'))
}
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
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