Hello @Aqsan, I will summarize this in an answer as it may be too lengthy for the comments section.
Based on my analysis, it seems that you need to trigger $scope.$digest/$apply() after your external code finishes executing or when the scope object of interest, vm.apidata, undergoes a change.
It is crucial to note that Angular expects vm.apidata to be a scope object. Merely inserting it into the global window/self scope does not align with what your markup refers to.
window.vm.apidata != scope.vm.apidata
If you are indeed updating the scope node correctly, you can utilize the same scope reference to invoke scope.$apply().
If you are unsure, here's some additional information.
For more insights, check out Scopes.
You can include references to the $rootScope, which serves as the top-level root scope in your services (provider, factory), controllers, and directives. Similarly, the $scope relevant in hierarchical contexts plays a role in controllers and directives, where it can be injected. Scope objects follow an inheritance pattern in a parent-child structure, except for isolated scopes found in custom directives or specific cases like ng-repeat directive. Here is a basic Controller implementation template where you can establish the connection:
var myModule = angular.module('myModule', []);
// This represents a Service
// notice how $rootScope is injected
// the array encapsulation around the factory function protects against JS code minification issues that might alter parameter names, rendering them invalid from an AngularJS standpoint
myModule.factory('retrieveService', ['$rootScope', '$q', function($rootScope, $q) {
function retrieve(){
// consider using Angular's $q service to return a promise
var deferred = $q.defer();
// Place your external code for data retrieval here
// Upon completion of async operation, call 'resolve' for success
deferred.resolve(<yourapidata>);
// Alternatively, handle errors by calling 'reject'
deferred.reject(<yourerror>);
// Optionally, set the value to $rootScope.vm.apidata and apply changes
$rootScope.vm.apidata = <yourapidata>;
$rootScope.$apply();
return deferred.promise;
}
return retrieve;
}]);
// This denotes a Controller
myModule.controller('MyCtrl', ['$rootScope', '$scope', 'retrieveService', '$q', function(rootScope, $scope, retrieveSvc, $q) {
function retrieve(){
// You can place your external code within the controller
// Handle async data retrieval here...
$scope.vm.apidata = <yourvalue>
}
// Ensure proper handling of asynchronous calls through promises or callbacks
retrieveService().then(function(apidata) {
$scope.vm.apidata = apidata;
// While $scope is recommended, alternatively,
// you could bind vm.apidata to $rootScope (either here or in the service) for inheritance by $scope
$rootScope.vm.apidata = apidata;
});
}])
This is just a starting point, and there's much more to explore and comprehend. The possibilities are vast, but hopefully, this sets you on the right path. Consider utilizing the $http Angular service, depending on your backend API requirements.