0

Goal: Send variable from Angular application to iFrame on that page but living on another server

Question: Why is document.getElementById returning null? Am I using DomSanitizer incorrectly or postMessage incorrectly?

(What I've tried)

Angular(localhost:4200)

chat.component.html:

<div class="iframe-container"> 
    <iframe id="iframe_chatui" src="{{ chatURL }}/loading.html" class="chatiframe" allow="microphone; camera"></iframe>
</div>

chat.component.ts:

const isIFrame = (input: HTMLElement | null): input is HTMLIFrameElement =>
    input !== null && input.tagName === 'IFRAME';

ngAfterViewInit() {        
        this.safeScript = this.domSanitizer.bypassSecurityTrustScript(this.localeId);
        let frame = document.getElementById('iframe_chatui');
        if (isIFrame(frame) && frame.contentWindow) {
                frame.contentWindow.postMessage(this.localeId, 'http://localhost:4200');
            }
    }

chatbox.aspx(localhost:7078):

<html>
    <body onload="onLoad()" onresize="onResize()" style="overflow-x: hidden;">   
        <div id="ChatPanel" class="patient-chat" >
            <div id="LiveChatLog" class="ChatLogBox"></div>
            <div id="UserEntryBar" class="UserEntryBar">            
                <div id="divFileUpload"> 
                    <button id="btnAddImage" onclick="ShowImageSourceDialog()" title="Add Image"><i class="icon-camera"></i></button>               
                </div>
            </div>
            <div id="divEndVisit" style="display:none;" >
                <button id="btnEndVisit" class="EndVisitButton btn" onclick="ConfirmEndVisitRequest();" >End Visit</button>
            </div>
            <div class="clearfix"></div> 
        </div>


        <script type="text/javascript">
            function receiveMessage(event) 
                    {
                        try 
                        {
                            if (event.origin === "[ROOT_SITE_URL]" ||
                                event.origin === "[ROOT_CHAT_SITE_URL]" ||
                                event.origin === "http://localhost:4200") 
                            {
                            }                       
            var receiveChatMsg = function (message) 
            {
                if(randomCondition) {}
                else if(desiredCondition) { window.addEventListener("message", receiveMessage, false); }
        </script>
    </body>
</html>
angleUr
  • 449
  • 1
  • 8
  • 27
  • How do you know it is returning null? Do you also get a null return if you select the container (i.e. `iframe-container`)? Also try changing the id so that it doesn't contain an underscore character: https://developer.mozilla.org/en-US/docs/Archive/Beginner_tutorials/Underscores_in_class_and_ID_Names. Or try grab it by its class instead of its ID> – geoidesic Jun 12 '19 at 23:29
  • @geoidesic Thanks. I am using DevTools in chrome looking at console and it shows null. When I try getting by class, I get error: "Argument of type HTMLCollectionOf is not assignable to parameter of type HTMLElement" *and* "Property contentWindow does not exist on type HTMLCollectionOf" – angleUr Jun 13 '19 at 00:23
  • Can you select the iframe thought the F12 console? is so you could try to defer it with window.setTimeout to also check when its inner content becomes available to use. if (null) return window.setTimeout(arguments.callee, 10); or else try document.querySelector('#iframe_chatui') – Steve Jun 13 '19 at 01:13
  • It's strange that even though the iFrame is in an ngIf=isLoaded , I tried not getting the variable until isLoaded was true, but its still null. – angleUr Jun 13 '19 at 14:47
  • @Steve isn't setTimeout considered bad practice? – angleUr Jun 13 '19 at 14:47
  • Did you try remove the underscore in the ID name? – geoidesic Jun 14 '19 at 08:31
  • When you get by class you will receive an array, so you should console.log that array and see whether the iframe is contained within.. of course your code which is not expecting an array will fail.. but if the iframe is within then you can easily pop the array. – geoidesic Jun 14 '19 at 08:32
  • @geoidesic yes, I was getting the same error for other ID's that did not have an underscore. I also tried it on the surrounding div with "iframecontainerId" no underscore and it still failed – angleUr Jun 14 '19 at 14:16
  • I suggest you create a jsFiddle or similar to show the problem with more specificity. – geoidesic Jun 14 '19 at 14:18
  • @geoidesic the surrounding div by class has length 0 but the iframe has length 1. It's HTMLCollection. You are saying to pop that first item from the array to be able to grab it? – angleUr Jun 14 '19 at 14:46
  • If I pop it, it's my understanding that it will no longer exist in the DOM, and thus I won't be able to postMessage to it – angleUr Jun 14 '19 at 15:04
  • Well you don't have to literally pop it. You can just reference it by index. E.g. `my_array[0]` – geoidesic Jun 14 '19 at 23:10

0 Answers0