I have a model that uses reactive forms and keeps giving me the error of regex.test is not a function.
The model is the following:
import { date, email, maxDate, maxLength, minDate, minLength, pattern, prop, required } from "#rxweb/reactive-form-validators";
export class UserInfo {
#required()
public firstName: string;
#required()
public lastName: string;
#pattern({expression: {pattern: /(^\+?[\d\W-/]{4,16}$)/ } })
#minLength({value: 4})
public phoneNumber: string;
}
And the error
ERROR TypeError: regex.test is not a function
at Function.isValid (reactive-form-validators.js:719)
at reactive-form-validators.js:3418
at forms.js:1155
at Array.map (<anonymous>)
at _executeValidators (forms.js:1151)
at RxFormControl.validator (forms.js:1096)
at RxFormControl._runValidator (forms.js:3438)
at RxFormControl.updateValueAndValidity (forms.js:3399)
at new FormControl (forms.js:3843)
at new RxFormControl (reactive-form-validators.js:2017)
happens when on the component I'm doing on the ngOnInit():
this.baseForm = this.formBuilder.formGroup(this.user) as RxFormGroup;
What is even stranger is that it only happens when I actually have data on the phoneNumber. If my phoneNumber is empty it works perfectly.
I even tested the following:
this.user.phoneNumber = "";
this.baseForm = this.formBuilder.formGroup(this.user) as RxFormGroup;
And this works. What is even stranger to me is that I did a small example on stackblitz and there it also works without any problem even with data.
It is working in my machine, please check the below image :
If you have sample not working example of pattern then please share the same
I've find out a solution and it was the following:
this.baseForm = this.formBuilder.formGroup(this.user) as RxFormGroup;
(this.baseForm .controls.phoneNumber as FormControl)
.addValidators(
[TextValidator.regexMatchValidator(new RegExp(/(^\+?[\d\W-/]{4,16}$)/), "error message")]);
basically add a validator after the form initialization
Related
I'm learning flutter by making an app following some youtube tutorials. I'm trying to make a listview of search results. I'm able to query and get data from node backend but there's this error while mapping the json to model.
The data I'm getting from api is like this:
{id: <uuid>,
userEmail: <email_string>,
profile: [{profileName: <profile_name_string>,
profileImage: <image_url_string>,
profileBio: <profile_bio_string>}]
}
With the new model class I made following an answer here I'm able to get profile model separately but when i try to get account model with all profiles I'm getting the error:type 'List<dynamic>' is not a subtype of type 'List<ProfileModel>?'. The model class is:
class AccountModel {
String userId;
String userEmail;
String? userPassword;
final List<ProfileModel>? profile;
AccountModel({
required this.userId,
required this.userEmail,
this.userPassword,
this.profile,
});
factory AccountModel.fromJson({required Map<String, dynamic> map}) {
return AccountModel(
userId: map['id'],
userEmail: map['userEmail'],
userPassword: map['userPassword'],
profile: map['profile']
.map((profileJson) => ProfileModel.fromJson(profileJson))
.toList(),
);
}
}
class ProfileModel {
String profileName;
String profileImage;
String? profileBio;
ProfileModel({
required this.profileName,
required this.profileImage,
this.profileBio,
});
factory ProfileModel.fromJson(profileJson, {Map<String, dynamic>? map}) {
if (map != null) {
return ProfileModel(
profileName: map['profileName'],
profileImage: map['profileImage'] ?? "default",
profileBio: map['profileBio'],
);
} else {
return ProfileModel(
profileName: profileJson['profileName'],
profileImage: profileJson['profileImage'] ?? "default",
profileBio: profileJson['profileBio'],
);
}
}
}
How to make the list work?
You can use List.from() in this case.
profile: map['profile'] != null
? List<ProfileModel>.from(
map['profile']?.map((p) => ProfileModel.fromJson(p)))
: null)
We are using fromMap here on ProfileModel, you can simplify just separation while both are same on ProfileModel.
More about List and List.from.
When you declared the list here as
final List<ProfileModel>? profile;
It expects the list to have only ProfileModels as ListItem even though with "?". The way to solve it is either declared a list without generic ProfileModel :
final List? profile;
Or to typecast the item you're pushing as ProfileModel.
2. profile: map['profile'] .map((profileJson) => ProfileModel.fromJson(profileJson) as ProfileModel) .toList(),
I don't know the output structures and such so try to experiment with typecasting if the above code doesn't work. May be typecasting after toList() method as List can work too.
I am migrating a big project from grails 2.5.4 to 3.3.10. Everything is going well but I have a mayor problem in my domain objects. I use to write my custom validators this way:
class Person {
String name
static constraints = {
name: nullable: false, validator: validateName
}
static validateName = {
// validation code
}
}
Grails throws the following exception
No such property: validatorTest for class: org.grails.orm.hibernate.cfg.HibernateMappingBuilder
In grails 3.x this way of defining validators seems to be broken. I know the documentation says to use this way:
name nullable: false, validator: { // code }
But it is a LOT of code to rewrite in that case.
Is there a way to use the old method of defining validators?
Thanks
See the project at https://github.com/jeffbrown/alejandroveraconstraints.
https://github.com/jeffbrown/alejandroveraconstraints/blob/master/grails-app/domain/alejandroveraconstraints/Person.groovy:
// grails-app/domain/alejandroveraconstraints/Person.groovy
package alejandroveraconstraints
class Person {
String name
static constraints = {
name nullable: false, validator: Person.validateName
}
static validateName = {
it != 'Some Bad Name'
}
}
https://github.com/jeffbrown/alejandroveraconstraints/blob/6701f61d61dbbde34f4925d1bf418448eee0a729/src/test/groovy/alejandroveraconstraints/PersonSpec.groovy:
// src/test/groovy/alejandroveraconstraints/PersonSpec.groovy
package alejandroveraconstraints
import grails.testing.gorm.DomainUnitTest
import spock.lang.Specification
class PersonSpec extends Specification implements DomainUnitTest<Person> {
void "test validation"() {
expect:
!new Person(name: 'Some Bad Name').validate()
new Person(name: 'Some Good Name').validate()
}
}
I have an "Index" controller method which returns a view with a Model that is a List<WhatsNew>. I am trying to validate this method in a unit test but it gives me an error as it is expecting a string.
Controller
public ActionResult Index()
{
return View("Index", GetWhatsNew());
}
public List<WhatsNew> GetWhatsNew()
{
WCMSDataContext wcmsContext = new WCMSDataContext();
return (from p in wcmsContext.WhatsNews select p).ToList();
}
Unit Test
[TestMethod]
public void Validate_Index_IList_WhatsNew_AS_Model()
{
AppItemController controller = new AppItemController();
// Act
var result = controller.Index();
// Assert
var model = ((ViewResult)result).Model as List<WhatsNew>;
Assert.AreEqual("Index", model.ToList());
}
Error
Assert.AreEqual failed. Expected:<Index (System.String)>. Actual: <System.Collections.Generic.List`1[WCMS.WhatsNew]
You're comparing a string "Index" with a List<WhatsNew>:
Assert.AreEqual("Index", model.ToList());
What exactly are you expecting to happen here?
You can check the contents of the model:
Assert.AreEqual(someValue, model.Count);
Assert.AreEqual(someOtherValue, model[0].SomeProperty);
You can also check the right page is being returned in the action:
Assert.AreEqual("Index", ((ViewResult)result).ViewName);
At the moment, you seem to be trying to mix the two...
You may want to have a read of something like this as a basic introduction to checking your controllers.
I am struggling a little with what to do after I call commit(). I want to determine how to route the user, depending on commit() being successful or if the server returns an error.
I read somewhere that if there is an error on the server then it can return a status code of >400 and errors as follows:
{ 'errors' : [ { 'errorCode' : [ 'duplicate-user' ] } ] }
On the client-side I have the following:
App.UsersController = Ember.ObjectController.extend({
createUser : function () {
'use strict';
var user = App.User.createRecord({
firstName : $("#firstName").val(),
lastName : $("#lastName").val(),
primaryEmailAddress : $("#primaryEmailAddress").val(),
password : $("#password").val()
}),
commitObserver = Ember.Object.extend({
removeObservers : function (sender) {
sender.removeObserver('isError', this, 'error');
sender.removeObserver('isValid', this, 'success');
},
error : function (sender, key, value) {
this.removeObservers(sender);
App.Router.router.transitionTo('duplicateuser');
},
success : function (sender, key, value) {
this.removeObservers(sender);
App.Router.router.transitionTo('usercreated');
}
});
user.get('transaction').commit();
user.addObserver('isError', commitObserver.create(), 'error');
user.addObserver('isValid', commitObserver.create(), 'success');
}
});
(Note: I am not using 'Ember.TextField' in my HTML hence the use of jQuery)
I have a few questions:
Is this the correct/best approach for handling commit()?
I've found I have to remove both observers as isValid is called after isError - is this to be expected?
How/can I access the server response as I want to be able to make a routing decision based on the error code?
The only way I can reference the router is through App.Router.router - is there a cleaner way?
If there is an error, do I need to do anything to remove the record from the store so it doesn't re-committed in the future?
From within a controller, you can do this:
this.get('target').transitionTo('another.route')
or, you can send an event to the current route and transition from there:
this.get('target').send('eventName');
or if you need to pass a model:
this.get('target').send('eventName', this.get('content'));
Simply use controller.transitionToRoute("your.route");
See this link for the source code...
I have a controller that uses a command object in a controller action. When mocking this command object in a grails' controller unit test, the hasErrors() method always returns false, even when I am purposefully violating its constraints. The more baffling thing is that in production, hasErrors() works! So this is just a testing problem.
def save = { RegistrationForm form ->
if(form.hasErrors()) {
// code block never gets executed
} else {
// code block always gets executed
}
}
In the test itself, I do this:
mockCommandObject(RegistrationForm)
def form = new RegistrationForm(emailAddress: "ken.bad#gmail",
password: "secret", confirmPassword: "wrong")
controller.save(form)
I am purposefully giving it a bad email address, and I am making sure the password and the confirmPassword properties are different. In this case, hasErrors() should return true... but it doesn't. I don't know how my testing can be any where reliable if such a basic thing does not work :/
Here is the RegistrationForm class, so you can see the constraints I am using:
class RegistrationForm {
def springSecurityService
String emailAddress
String password
String confirmPassword
String getEncryptedPassword() {
springSecurityService.encodePassword(password)
}
static constraints = {
emailAddress(blank: false, email: true)
password(blank: false, minSize:4, maxSize: 10)
confirmPassword(blank: false, validator: { confirmPassword, form ->
confirmPassword == form.password
})
}
}
Have you tried mockForConstraintsTests ?
E.g. something like...
void testSomething() {
mockForConstraintsTests(RegistrationForm)
def form = new RegistrationForm(emailAddress: "ken.bad#gmail", password: "secret", confirmPassword: "wrong")
form.validate()
assert 1 == form.errors.getErrorCount()
}
Try just testing the RegistrationForm command object first in its own unit test. (gain some confidence that its actually working)
Maybe using the above for the basis of your test will help!?!?