I have been trying to render image in an external web-component inside react but couldn't do it.
I am working on a react app that would use HTML template that can be run in browser, template is something like:
<script src="https://assets.some-domain.com/someBundledjs.js"></script>
<ParentForm>
<ChildForm name="entryForm" image-src="https://www.image-domain.com/person1.jpg">
</ChildForm>
</ParentFrom>
I tried to render it in reactDOM using react-helmet. Everything works fine except the image doesn't load in browser(though the call to fetch the image succeeds). When I debugged(luckily I have access to source code generating above form), I came to know that that the image is loading during server-side rendering, before js is downloaded, hence the image.onLoad() callback in the source code is never called. I verified it as per ref.
Update(rendering js without react-helmet):
I tried rendering below in react after loading script by doing something like:
componentDidMount () {
const script = document.createElement("script");
script.onload = () => {
// script has loaded, you can now use it safely
this.setState({ isLoadParentForm: true });
}
script.src = "https://assets.some-domain.com/someBundledjs.js";
script.async = false;
document.body.appendChild(script);
}
render(){
return(
<div>
{this.state.isLoadParentForm?
<ParentForm>
<ChildForm name="entryForm" image-src="https://www.image-domain.com/person1.jpg">
</ChildForm>
</ParentFrom>
: <></>
</div>
)
}
This ensures that the component is rendering post the script has loaded, still the image doesn't load inside the component.
Can someone explain and provide solution?
After spending lot of time I finally figured out the root cause. The react-app that we are using downloads bunch of javascript libraries. One of those libraries has a js file that overrides the Image constructor. Due to this the image src was not getting set as expected and hence the image failed to load.
Related
I have a few web pages that load Javascript files with the same basic structure.
page.html
<script src="js/common.js"></script>
<script src="js/page_specific.js"></script>
I now want to make a change to my pages to load some data from a backend server before running the page_specific.js.
The way I have done this so far is to remove the page_specific.js script tag from the HTML, create a Promise in the common.js that resolves once it has the data from the server. Then in the page.html I load the page_specific.js once the Promise is resolved:
// Load the options first (in common.js) and then load page specific js.
loadOptions.then(() => {
var js = document.createElement("script");
js.onload = () => {
page_specific.Init();
}
js.src = "js/page_specific.js";
document.body.appendChild(js);
});
This works but it, of course, means I have to change each of my pages (remove the script tag and add JS to load it dynamically later as per above).
Is there a way to achieve something similar that doesn't require changing every page (e.g. within common.js)? If not, is there any downside to the above method?
ETA: there is also a page specific function that is called from the HTML (different names). I've added the onload in code above.
I am trying to learn how to display small widgets (for example plane tickets brower) onto my website built in Reactjs. The code that's supposed to work instantly according to the provider is as below ("just copy and paste into website"):
<div id="widget" data-widget="search" data-affiliate="873" data-campaign="873-"></div>
<script src="https://widget.wakacje.pl/v2/public/js/widgets/search-widget.js?c=widget" async></script>
I tried to Google for answers and my idea atm looks like this:
function OfferBrowser() {
const script = document.createElement("script");
script.src = "https://widget.wakacje.pl/v2/public/js/widgets/search-widget.js?c=widget";
script.async = true;
return(
<div id="widget" data-widget="search" data-affiliate="873" data-campaign="873-"></div>
)
}
The other this I tried was also to put {script} into the tag like this, but it doesn't work as well.
<div id="widget" data-widget="search" data-affiliate="873" data-campaign="873-">{script}</div>
How should I approach this?
While I don't know React, I believe I have found the problem with the second chunk of code. You have created a script element, but have not added it to the DOM, and therefore it's not loading the script.
After looking around for a bot, I believe I've found a fix.
const script = document.createElement("script");
script.src = "https://widget.wakacje.pl/v2/public/js/widgets/search-widget.js?c=widget";
script.async = true;
// append the script tag to the body
document.body.appendChild(script);
I think this needs to run after the component is mounted, so that the div is in the DOM.
Edit
I decided to try adding the script tags to the index.html file and conditionally rendering them.
<script type="text/javascript">
var $show_stuff = 'no';
var $add_stuff = 'yes';
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'https://www.example.com/includes.php?stuff=true';
document.getElementById('feed').appendChild(script);
</script>
Then in the component I want the feed to show up I did this,
<div id="credit-feed" />
I also tried conditionally rendering the script tag in the index.html file like this,
if(window.location.href === "localhost:3000/my/path" ) { script tag... }
These both do not work as well. The script tag does not show up in the div in the first example and the second does show the script tag but it does not render.
But, when I add the script tag like normal to the head of the HTML file, the feed renders as I would expect.
Background
We do business with a company that provides us a Javascript script tag which appends the data from it's response into the body of our web page. We have had a PHP site for the past 8 years without problems but now that we are switching to React, we can not figure out the correct way to use this tag in the component it will live.
Problem
When we add the script tag to the React component, it does not append the correct data to the page. In fact it does not append any data to the page.
Example
I have tried to load the script tag like normal,
<script type="text/javascript">
var $somevar = "false";
var $addjquery = "yes";
</script>
<script
type="text/javascript" src="https://www.example.com/do/deef.php?feedtype=all ">
</script>
Another way I have tried in the React component,
componentWillMount() {
const script = document.createElement('script');
const $somevar = 'false';
const $addjquery = 'yes';
script.src = 'https://www.example.com/get/feed.php?&data=all';
script.async = true;
document.body.appendChild(script);
}
Question
What is the correct way to load the script tag so it will append the data to my application?
Usually with a React app, you will have an index.html file that contains the React component. You should put the <script> reference inside the html file. So I would definitely use the first approach you mention. If it's not loading, can you check the browser inspector and find out what kind of error you are getting? For one thing, you should remove the empty white space from the URL. That could be the issue.
I have the following bit of code in my global index.js file in React:
const script = document.createElement('script');
script.src = 'assets/js/custom.js';
script.async = true;
document.body.appendChild(script);
This injects a script tag to the body of the dom. This doesn't quite work as expected, it appends the file but it doesn't trigger any of the jQuery code in the file.
However if I put the exact same script in a componentDidMount function of one of my components it works fine.
I don't want to add this to each and every component, How can I do this globally?
Thanks
I'm creating a Java Script widget for the site based on CodeIgniter. The site using templates and Blade library. I need to load my java script right after the page has been loaded. I have added it into template scripts.blade.php:
<script src="{{apps_url('assets/my_widget/js/my_widget.js')}}"></script>
Unfortunately, it seems, what my script was executed before controller has been loaded and therefore the script can not find required SVG object:
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
This alert show what container is null even if the myContainer object actually exists on the page and was recognized by CSS. The d3 library has been loaded properly and there is no errors in the Firefox console.
Is there a way to execute this script right after the object has been loaded?
use
$(document).ready(function() {
(function() {
var container = d3.select(".myContainer");
alert("container: " + container);
})();
});