Undefined elements when calling update()

I’m using a template made in google web designer.

The html loads fine in chrome, and sending the update command with a proper string results in the template running and everything flows according to plan.

But when loading the template in casparcg, when update() is called the elements it is trying to change values don’t exist yet, and the template crashes out or does not update the elements.
I’ve come to this conclusion logging variables to console, and they are undefined then update() tries to access them.

Any way to avoid this situation?
setTimeout’ing the insertion code to only run after 2000ms fixes this, but is no solution.

I am a novice JavaScript programmer, still trying to figure out my way trough it. But I think I read somewhere, that there is an event called “window.loaded” or something similar, that you can subscribe to and that gets fired after the page has finished loading. That should do the trick.

It’s hard to help without you posting your code. My guess is that you are defining update() before the element exits, move your update() to a <script> tag just before </body> or wrap update/play/stop() etc… in:

window.addEventListener('DOMContentLoaded', function() {
// ORIGINAL CODE HERE
});
1 Like

my script is the last thing before :

  <script src="script.js"></script>
</body>

Wrapping the functions in
window.addEventListener
also doesn’t work.

I’ll be uploading the code if anyone is interested to check it out.

Yes, sure.

here. It looks like it loads and works fine first time the server is started, which is even more confusing for me.

Still stuck.
CG ADD the template first and then CG PLAY. Also doesn’t work.

Anyone using Google Web Designer having the same issues?

I solved it by waiting between data() and play() for an event that my element was loaded:

use the https://github.com/indr/webcg-framework

Here only at first load webcg.on(‘data’) waits until it gets an ElementLoaded-event to fullfill it’s promise. Then play() will be triggered.

webcg.on('data', function (data) {
			var datafield = (data.f0 ? data.f0.text || data.f0 : '');
			return new Promise(function(resolve, reject) {
				if(tpstate){
					//set myelements field with datafield;
					resolve();
				}else{
					document.getElementById('container').addEventListener("ElementLoaded", function(event) {
						//set myelements field with datafield;
						resolve();
					},{once: true});
				}		
			});
		})

Which Event you wait for depends on what you do. In my case I throw my ElementLoaded-event when a bodymovin-animation was added to the DOM:

var tpstate;
document.addEventListener("DOMContentLoaded", function(event) {
     myelement = bodymovin.loadAnimation({
				container: document.getElementById('container'),
				path: 'path-to-my-bodymovin-data.json', 
				renderer: 'svg',
				loop: true, 
				autoplay: true});

    myelement.addEventListener("DOMLoaded", function(event) {
		tpstate = true; 
               document.getElementById('container').dispatchEvent(newEvent('ElementLoaded'));
      });
});

    

where do you load that second snippet? i’ve tried to make it work but no luck so far.

The second snippet is the standard event when all HTML was added to the DOM:

thanks, but i’m not getting to what i want to… probably due to a bad implementation on my end.