Currently in my project, I am facing a scenario where I have multiple models performing similar actions. To streamline this process, I am looking to refactor by creating a generic "BaseModel" stored within a service.
Previously, within my old models, I would inject a 'ValidatorService' and utilize functions like 'ValidatorService.isValidStreetNumber(streetNumber)'. This approach worked well as the Model service could easily access the ValidatorService (Singleton) function.
It's worth noting that I am now passing the validation/normalization functions anonymously through prototypal inheritance (typeValidator, contentValidator, contentNormalizer).
Now, with these changes, the structure of my generic class in Coffeescript appears as follows:
app = angular.module 'app'
BaseModel = ()->
Model = (data, defaultData, isRequired, errorMessage, \
typeValidator, contentValidator, contentNormalizer)->
this.defaultData = defaultData
this.isRequired = isRequired
this.errorMessage = errorMessage
this.typeValidator = typeValidator
this.contentValidator = contentValidator
this.contentNormalizer = contentNormalizer
this.data = this.initialValue(data)
this.isValid = this.contentValidator(this.data)
return
Model.prototype.initialValue = (value)->
if not this.typeValidator(value)
return this.defaultData
return value
Model.prototype.updateValidity = ()->
this.isValid = this.isValidModel()
return
Model.prototype.isValidModel = ()->
if not this.typeValidator(this.data)
return false
emptyOptional = not this.isRequired and
angular.equals(this.data, this.defaultData)
return emptyOptional or this.contentValidator(this.data)
Model.inherit = (data, defaultData, isRequired, errorMessage, typeValidator, contentValidator, contentNormalizer)->
return Object.create(new Model(data, defaultData, isRequired, errorMessage, typeValidator, contentValidator, contentNormalizer))
return Model
BaseModel
.$inject = []
app
.service 'BaseModel', BaseModel
The setup for initializing a simple inheriting class is demonstrated below:
Street = (streetName)->
defaultData = ""
isRequired = true
errorMessage = ValidatorService.errorMessageStreet()
typeValidator = ValidatorService.isValidString
contentValidator = ValidatorService.isValidStreet
return BaseModel.inherit(streetName, defaultData, isRequired, \
errorMessage, typeValidator, contentValidator)
While this method works effectively when the passed functions are isolated without any external references, I encountered issues when the "ValidationService" functions were calling other functions using "this." The anonymized functions started throwing errors.
For instance:
this.isValidName = (string)->
regexp = this.internationalLettersNumbers("{1,60}")
return this.isRegexpMatch(string, regexp)
At present, the only workaround I can think of involves ensuring that the validation functions do not reference any additional functions or libraries. However, this solution is limiting as it restricts my access to other services like 'LocaleService'. I'm currently at an impasse and seeking a viable way to resolve this issue. Is there perhaps an "angular" approach that could provide a solution?
Your insights and suggestions are greatly appreciated!