nspessot nspessot - 1 month ago 9
Javascript Question

Angular custom directive not setting value after promise resolve

I have a custom directive, it works great when user is entering value, the problem is when loading the form, the input field is not being rendered.
Here is my directive:

var cuitModule = angular.module('cuitModule', []).directive('cuitDirective', ['$filter', function ($filter) {
return {
require: '?ngModel',
link: link,
restrict: 'E',
scope: {
cuitPlaceholder: '=placeholder'
},
templateUrl: 'js/common/directives/cuit/cuit.directive.html'
};

/*
Intended use:
<cuit-directive placeholder='prompt' model='someModel.cuit'></cuit-directive>
Where:
someModel.cuit: {String} value which to bind only the numeric characters [0-9] entered
ie, if user enters 20-33452648-9, value of 20334526489 will be bound to model
prompt: {String} text to keep in placeholder when no numeric input entered
*/
function link(scope, element, attributes, ngModel) {

// scope.inputValue is the value of input element used in template
scope.inputValue = ngModel.$viewValue;

scope.$watch('inputValue', function (value, oldValue) {

value = String(value);
var number = value.replace(/[^0-9]+/g, '');
// scope.cuitModel = number;
scope.inputValue = $filter('cuit')(number);
var valid = validarCuit(number);
ngModel.$setValidity('required', valid);
if (valid) {
ngModel.$setViewValue(number);
}
});

//source https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Identificaci%C3%B3n_Tributaria#C.C3.B3digo_Javascript
function validarCuit(cuit) {

if (cuit.length !== 11) {
return false;
}

var acumulado = 0;
var digitos = cuit.split('');
var digito = digitos.pop();

for (var i = 0; i < digitos.length; i++) {
acumulado += digitos[9 - i] * (2 + (i % 6));
}

var verif = 11 - (acumulado % 11);
if (verif == 11) {
verif = 0;
}

return digito == verif;
}
}}]).filter('cuit', function () {
/*
Format cuit as: xx-xxxxxxxx-x
or as close as possible if cuit length is not 10
*/
return function (number) {
/*
@param {Number | String} number - Number that will be formatted as cuit number
Returns formatted number: ##-########-#
if number.length < 2: ##
if number.length < 10: ##-########
if number.length === 11: ##-########-#
*/
if (!number) {
return '';
}

number = String(number);

// Will return formattedNumber.
// If phonenumber isn't longer than an area code, just show number
var formattedNumber = number;

//Type 20, 23, 24 y 27 Personas FĂ­sicas or 30, 33 y 34 Empresas
var type = number.substring(0, 2);

var main = number.substring(2, 10);
var verifyNumber = number.substring(10, 11);

if (main) {
formattedNumber = (type + '-' + main);
}
if (verifyNumber) {
formattedNumber += ('-' + verifyNumber);
}
return formattedNumber;
};});


This is the html:

<cuit-directive placeholder="'CUIT'" ng-model='vm.merchant.idNumber' required></cuit-directive>


I am invoking it within a form of course.

I am getting the data to my controller through a rest service, so I am doing something like:

function EditMerchantCtrl($state, $ionicHistory, merchantsService, $ionicPopup, $timeout, $ionicLoading) {
var vm = this;
function init(){
merchantsService.get().then(
function(response){
vm.merchant = response.data;
});
}}


I don't know why I can't get that field populated after receiving the response from the service. Any help would be much appreciated.

Answer

You should implement the $render function of the ngModelController, try something like this:

ngModel.$render = function() {
   scope.inputValue = ngModel.$viewValue;
}

Hope it helps.

Comments