0

I want to refresh the method $scope.getPIRData dynamically according to the text box value , I have one text box where I can give some seconds like 3000 ms , that I need to get into the setInterval block but my text box values not setting to the window.refreshtime.

Method is refreshing properly but after selecting the dropdown list the refresh mechanism not working before selecting the dropdown only it is working fine.

html

<input type="number"
                   ng-model="refreshtime"
                   ng-model-options="{ updateOn: 'blur' }"
                   ng-change="setupInterval()"
                   id="txtRefresh" name="name" />


<select class="form-control ng-pristine ng-valid ng-scope ng-empty ng-touched" ng-model="sel_val" ng-change="getPIRData(sel_val.deveui)" ng-options="data.details for data in pirs">Select PIR Device</select>

Java script

var app = angular.module('PIR_Detection', []);
    app.controller('myCtrl', function ($scope, $http, $window, $timeout) {
        $scope.sel_val = 0;
        $scope.DefaultLabel = "Loading.....";
        $scope.refreshtime = 1000;
        var post = $http({
            method: "get",
            url: "../data.json",
            dataType: 'json',
            data: {},
            headers: { "Content-Type": "application/json" }
        });
        post.success(function (data, status) {
            $scope.pirs = data;
        });
        post.error(function (data, status) {
        });

        $scope.getPIRData = function (id) {
            var url = "/PIRDetails/GetPIRStatus/" + id;
            $http.get(url)
                .then(function (response) {
                    $scope.myWelcome = response.data;
                    if ($scope.myWelcome != "") {
                        $scope.pirstatus = base64toHEX($scope.myWelcome.dataFrame);

                    }
                    $window.deviceId = id;
                })
                // next call will be made after the request
                .finally($scope.setupInterval);
        };

        let timeOut = null;
        $scope.refreshPIR = function () {
            if (timeOut) {
                // removes the previous timeout from event loop
                $timeout.cancel(timeOut);
            }

            console.log('timeout method call at ', $scope.refreshtime, 'ms');

            timeOut = $timeout(function () {
                if ($window.deviceId) {
                    $scope.getPIRData($window.deviceId);
                } else {
                    $scope.refreshPIR();
                }
            }, $scope.refreshtime);
        };

        //init
        $scope.refreshPIR();
    });

2 Answers 2

1

use setTimeout over setInterval to get more control over the execution (https://weblogs.asp.net/bleroy/setinterval-is-moderately-evil).

AngualrJs has inbuilt $timeout service, which takes care of the digest cycle.

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

app.controller('myCtrl', function ($scope, $http, $window, $timeout) {
    $scope.sel_val = 0;
    $scope.DefaultLabel = "Loading.....";
    $scope.refreshtime = 1000;

    // commenting the data code, just for the solution demo
    /* var post = $http({
        method: "get",
        url: "../data.json",
        dataType: 'json',
        data: {},
        headers: { "Content-Type": "application/json" }
    });
    post.then(function (data, status) {
        $scope.pirs = data;
    });
    post.catch(function (data, status) {
    }); */

    $scope.getPIRData = function (id) {
        var url = "/PIRDetails/GetPIRStatus/" + id;
        $http.get(url)
            .then(function (response) {
                $scope.myWelcome = response.data;
                if ($scope.myWelcome != "") {
                    $scope.pirstatus = base64toHEX($scope.myWelcome.dataFrame);
                }
                $window.deviceId = id;
            })
            // next call will be made after the request
            .finally($scope.refreshPIR);
    };

    let timeOut = null;
    $scope.refreshPIR = function() {
      if(timeOut) {
        // removes the previous timeout from event loop
        $timeout.cancel(timeOut);
      }

      console.log('timeout method call at ',$scope.refreshtime, 'ms');

      timeOut = $timeout(function() {
        if($window.deviceId) {
          $scope.getPIRData($window.deviceId);
        } else {
          $scope.refreshPIR();
        }
      }, $scope.refreshtime);
    };


    //init
    $scope.refreshPIR();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="PIR_Detection" ng-controller="myCtrl">
    Refresh interval: 
  
  <!-- Used ng-model-options to fire the change event once user comes out the textbox-->
  <input type="number" 
  ng-model="refreshtime" 
  ng-model-options="{ updateOn: 'blur' }" 
  ng-change="refreshPIR()" 
  id="txtRefresh" name="name"/>
  
</div>

Sign up to request clarification or add additional context in comments.

4 Comments

its almost working but the thing is its working on page load. after selecting dropdown list refreshing the method not working , once the dropdown list is selected the console.log not showing, can u check my updated code
@krishnamohan it should be $scope.refreshPIR in .finally - corrected my code, plz update and try again
thanks for such a great code and support. its working fine for me.can u tell where the ng-change="setupInterval() used in my code im not able to find the usage of this ng change event
@krishnamohan corrected my code, Initially, I had the function name as setupInterval then renamed to refreshPIR - forgot to rename everywhere.. now updated the code.
0

Ok so two things... first of all, note the misspelling in $scope.refrestime. That being said, this won't fix your problem. setInterval's interval is set when you call it and cannot be changed.

Seeing as you seem to want to only change the interval on the next time the interval hits, What you can do is pull the function out of the setInterval and into its own reference and instead of setInterval simply use setTimeout and then as the last line of the function just call setTimeout(refreshPIR, $scope.refreshtime)

function refreshPIR() {
  if (window.deviceId != null) {
    $scope.getPIRData(window.deviceId);
  }
  setTimeout(refreshPIR, $scope.refreshtime);
}

setTimeout(refreshPIR, window.refreshtime);

Tho you might want to add some error handling to make sure scope.refreshtime is an int :-)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.