How do I call a controller function after my object has loaded?

Issue

I’m very new to angularjs, so this may be a very obvious to a lot of you…

I have a "main" view with a "MainCtrl" controller. The controller has a "$scope.init()" function that is being called when the controller is initialised.
However, I have an iFrame in the view that needs to complete it’s "onload" js function before the "init" function can successfully run.

I tried triggering the "init" function using the iFrame’s ngInit, but that happens before the "onload"

Please can you tell me how to make init function run after the iFrame’s onload="otherFunction" has finished?

Solution

Created a demo below where ng-init="increaseCount()" increases the value of $scope.carCount variable but only after the <iframe> was loaded.

You can load the <iframe> by clicking on the button and watch how $scope.carCount changes.

Not sure if this is the right way though.

Basically, I have 2 functions inside my INIT function named increaseCount():

  1. A function increaseCount which contains the main INIT logic ie. increasing the amount of cars
  2. A function onIframeLoad which waits until the iframe is loaded and then executes main INIT logic by calling increaseCount();

Interactive DEMO here or run the code below ↓↓↓

var app = angular.module('App', []);

// Allow iframe loading from various sources
app.config(["$sceDelegateProvider", function($sceDelegateProvider) {
    $sceDelegateProvider.resourceUrlWhitelist([
        // Allow same origin resource loads
        "self",
        // Allow YouTube iframes
        "https://www.youtube.com/embed/**"
    ]);
}]);

// Allow a directive "iframe-onload" in HTML
app.directive('iframeOnload', [function(){
return {
    scope: {
        callBack: '&iframeOnload'
    },
    link: function(scope, element, attrs){
        element.on('load', function(){
            return scope.callBack();
        })
    }
}}]);

// Main controller
app.controller('MainCtrl', function($scope, $sce) {
  $scope.car = 'Mercedes';
  $scope.carCount = 0;
  $scope.iframeSource = "";
  
  // INIT
  $scope.increaseCount = function () {
 
    // First wait on iframe load
    $scope.onIframeLoad = function () {
      console.log('Iframe fully loaded');
      
      increaseCount(); // If iframe loaded then execute main INIT logic
    };
    
    
    // INIT body - main INIT logic
    function increaseCount () {
      $scope.$apply('carCount = 10'); // change $scope.carCount to 10
    }
    
  };
  
  // Load iframe when clicked on the button
  $scope.loadIframe = function () {
    console.log("Clicked on the button.");
    $scope.iframeSource = "https://www.youtube.com/embed/Ra__OWuOU1M";
  }
  
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>

<div ng-app="App" ng-controller="MainCtrl" ng-init="increaseCount()">

  <h1>{{ car }} count: {{ carCount }}</h1>

  <iframe iframe-onload="onIframeLoad()" ng-src="{{ iframeSource }}"></iframe>
  
  <button ng-click="loadIframe()">Load Iframe</button>
  
</div>

Answered By – DVN-Anakin

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published