krishna mohan
krishna mohan

Reputation: 147

How to send text box value to the controller using ng-model in angular js

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();
    });

Upvotes: 0

Views: 66

Answers (2)

ajai Jothi
ajai Jothi

Reputation: 2294

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>

Upvotes: 1

Leroy Stav
Leroy Stav

Reputation: 718

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 :-)

Upvotes: 0

Related Questions