Losing Context in AngularJS 1.6 When Passing Service Function to Generic Model

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!

Answer №1

It seems that there is a solution to this issue by avoiding the use of 'this' and instead directly referring to the model object returned by the service. Even though I have not been able to fully replicate the problem in my unit tests, the approach can help prevent it:

validatorService.prototype.validateName = (str)->
    pattern = validatorService.prototype.getPatternForName("{1,60}")
    return validatorService.prototype.matchPattern(str, pattern)

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I access dynamically created input elements without using $refs, such as getting focus?

Is there a way to handle dynamically created inputs for editing purposes without using jQuery or vanilla JS all the time? Each input element has its own ID and is displayed through v-if when editing is triggered. However, Vue does not recognize them in r ...

What strategies can be used to resolve the problem of image hover?

I have a unique idea for my webpage where I want to showcase a grid view of black and white images. When I hover over each image, it transforms into a colored version. Additionally, clicking on an image will not only change it to color but also add a tick ...

Guide to scraping a website using node.js, ASP, and AJAX

I am currently facing an issue where I need to perform web scraping on this specific webpage form. This webpage is dedicated to vehicle technical reviews, and you can try inputting the car license CDSR70 for testing purposes. As mentioned earlier, I am u ...

Validation of input in React using the onChange event handler

When trying to validate a numeric input using onChange in React, I encountered an issue where the input clears and React throws a ReferenceError: value is not defined. This error makes sense since there is nothing to validate when the input is empty. I ca ...

The React page on localhost is displaying a void of content with just a white background, no elements are

Can someone help me figure out what I'm doing wrong with my codes? I recently used a website called robohash to generate random robot images based on the text provided. For example, robohash.org/test was utilized in my code. The command prompt indic ...

Performing an AJAX request to validate a username when it loses

Hey everyone, I'm currently working on a script that checks the availability of a username in a MySQL database using an onblur event with AJAX. Here's the AJAX script: document.getElementById("r_username").onblur = function(){ var http ...

Exploring the use of @Query() object in Nest.js for iteration

How can we loop through an object passed to the controller using @Query() annotations? We are dealing with a varying number and names of query parameters in our GET request, so we require the entire @Query() object to iterate through and determine the exa ...

Performing a password-protected JavaScript Ajax request that includes special characters

Within my JavaScript page, I have implemented an Ajax call shown in the code snippet below. The PHP page resides within a corporate intranet that demands domain authentication (without basic auth). To extract the username (u) and password (p), I am using j ...

Triggering a method inside an AngularUI Accordion template with ng-click

I have a question regarding the AngularUI bootstrap library and templates. I want to call a custom method within the template instead of using ng-click="isOpen = !isOpen". Can anyone provide guidance on how to achieve this? Any help is appreciated. <d ...

The character 'T' cannot be assigned to the data type 'number'

When working with an optional type argument function RECT(T), I encountered a situation where I need to check if the argument is an instance of date. If it is, I convert it to a number; if not, I use the number directly. However, I keep getting an error ...

Is it possible to delete an element from a JSON file by solely utilizing the element's ID?

I'm fairly new to JavaScript and I've tried various online solutions without success. Currently, I'm working on creating a backend for a todo list application where I aim to implement the feature to delete items from the list. Below is the ...

Sending data through a form using AJAX and PHP

Greetings! I've developed a page that allows users to view results for a specific tournament and round. The user will first select a sport, which will then populate the available tournaments based on the sport selection. Following this, the user can ...

Using Mongoose and Node.js, employing Object.assign to duplicate the data retrieved from the database reveals supplementary information

Today I stumbled upon something intriguing, a concept that was previously unknown to me. I am seeking guidance to comprehend the reason behind this occurrence: User.findOne({email: req.body.email}, function(err, usr){ return res.json({ RAW: ...

The $http.then callback is failing to be executed

I am encountering an issue with a $http.post call where the callback function is not getting called. Surprisingly, I have another call with identical code that works perfectly fine. Can anyone spot any problems in the code snippet below? var data = {entit ...

Unable to convert the existing JSON array into the specified type

I've been struggling to find a solution to this problem, even though I've come across similar topics that have been asked before. Below is a sample Json that I'm posting to a web API controller: { "AppointmentId ":2079, "ma ...

When attempting to change the text in the textarea by selecting a different option from the dropdown list, the text is not updating

I am facing an issue with three multi-select dropdown lists. When a user selects options from these lists and then presses the submit button, the selected text should display in a textarea. However, if the user manually changes some text in the textarea ...

In Typescript, if at least one element in an array is not empty, the function should return false without utilizing iterators

My current approach involves receiving a string array and returning false if any of the elements in the array is false. myMethod(attrs: Array<String>) { for (const element of attrs) { if (!element) { return false; } } ...

Refreshing Javascript on browser resize for a BXslider carousel: How to do it

I have implemented a BXslider carousel and I am looking to adjust the number of static slides displayed based on the screen width. My attempt to use jQuery resize() to achieve this is not functioning correctly. You can check out the live demo here: pepnes ...

Helping React and MUI components become mobile responsive - Seeking guidance to make it happen

My React component uses Material-UI (MUI) and I'm working on making it mobile responsive. Here's how it looks currently: https://i.sstatic.net/kxsSD.png But this is the look I want to achieve: https://i.sstatic.net/kJC2m.png Below is the code ...

What methods work best for handling extensive arrays in Javascript language?

I am currently working on a React JS application that interacts with an API to fetch a JSON object containing a large array of over 10,000 objects. This array is then used to populate a table with the help of various filters and options available through c ...