-1

I'm trying to render a default message on a textarea using AngularJS. Some of the values I'm trying to add requires the use of $timeout in order to obtain the values.

The message doesn't seem to render using the code below:

    <textarea class="text-input referral-message" ng-init="message=buildMessage(purchase_count)" 
              ng-model="message" rows="5">
    </textarea>

$timeout(function() {

    ReferralService.settings().$promise.then(function(settings) {
        $scope.purchase_count = settings.credits;
    });

    $scope.buildMessage = function(val){
      return "Buy " + val + " and get 1 free for every purchase"
    }
}, 1);
Graham
  • 7,431
  • 18
  • 59
  • 84
clestcruz
  • 1,081
  • 3
  • 31
  • 75
  • 1
    What purpose is the $timeout serving? Setting a timeout of 0 (or 1 i suppose) is occasionally needed in order to wait for the current event queue to clear, but i don't see anything in your example that would compel that. – Nicholas Tower Sep 13 '17 at 09:50
  • Possible duplicate of [Insert data-bind values inside textarea as a default canned message using angular](https://stackoverflow.com/questions/46192941/insert-data-bind-values-inside-textarea-as-a-default-canned-message-using-angula) – Stanislav Kvitash Sep 15 '17 at 10:44

3 Answers3

1

Look for the scope.apply function and try something like this (I'm writing this from my memory, don't expect to be fully functional):

ReferralService.settings().$promise.then(function(settings) {
  $scope.$apply(function(){
     $scope.message = "Buy " + settings.credits + " and get 1 free for every purchase";
  });
});

And:

<textarea class="text-input referral-message" ng-model="message" rows="5">
</textarea>

Edit: Take into account that $timeout may not be necessary.

Edit2: Have a look for implementing ReferalService as a factory (angular.service vs angular.factory) i may also help you.

Fibman
  • 126
  • 9
1

You can use {{}} to display content from the data model

<textarea class="text-input referral-message" rows="5">{{message}}
</textarea>

$timeout(function() {

ReferralService.settings().$promise.then(function(settings) {
    $scope.purchase_count = settings.credits;
    $scope.message = "Buy " + $scope.purchase_count + " and get 1 free for every purchase"
});

}, 1);
Aparna
  • 572
  • 4
  • 9
  • Use of $timeout breaks asynch logic. It's not needed and I'm quite sure to be like a bad way to do things. Then, not using ng-model makes textarea unuseful for sending $scope items as a form on a submit function, which may be the point here. – Fibman Sep 15 '17 at 10:29
1

Using ngInit in your case is not a good practice, since it adds unnecessary amount of logic into your template.

Simply remove ng-init from the textarea and initialize your message variable when the promise is resolved:

ReferralService.settings().$promise.then(function (settings) {
    $scope.message = buildMessage(settings.credits);
});

function buildMessage(val) {
    return "Buy " + val + " and get 1 free for every purchase"
}
Stanislav Kvitash
  • 4,614
  • 18
  • 29
  • I like that, but message may be not be updatable when a asynch call happens. With a $scope.$apply function it may be solved and it drives to my answer, but preserving the buildMessage function. – Fibman Sep 15 '17 at 10:27
  • @Fibman `$scope.$apply` is needed if the change happens outside of the angularjs scope and calling it could lead to `$digest already in progress` erros; if `ReferralService` is using [`$resource`](https://docs.angularjs.org/api/ngResource/service/$resource) or [`$http`](https://docs.angularjs.org/api/ng/service/$http) (I assume so), then `$apply` is not needed since the handlers are called in the context of $apply block. It depends on `ReferralService` implementation. But anyway I see the author has asked the same thing in his previous post, so probably better to mark this as a dupe. – Stanislav Kvitash Sep 15 '17 at 10:44
  • That explanation is very clarifying. I used angular.factory and I needed the $apply almost always. – Fibman Sep 15 '17 at 10:57