.value on form group shows numeric values as null or "" - javascript

im having trouble getting data from a form group. I have this formGroup called lineitemForm, and I'm wanting to format said form group in the following:
private formatTransferData() {
const depositDates = this.getDepositDates(this.lineItemsForm);
const mappedValues = this.formatFormValues(depositDates);
return this.filterFormValues(mappedValues);
}
private formatFormValues(depositDates) {
return depositDates.map((depositDate) => {
return {
effectiveDates: depositDate.controls.effectiveDates.value,
depositDate: depositDate.controls.depositDate.value,
};
});
}
I have been noticing that the function formatTransferData() breaks down when I pass depositDates into this.FormatValues(), there are two numeric variables inside of depositDates, I can console.log inside the mapping depositDate.controls.effectiveDates and see two numeric values, but as soon as I add on the .value to the end the numeric values either resolve themselves to null or a simple "", is there some sort of conflict that I am unaware of when using .value on a formGroup that contains numeric value/s?

On later reflection, the best way to go about getting values from a formGroup is by doing the following:
this.formGroup.controls['someFormGroupValue'].value
or
this.someForm.get('someFormItem').value;

Related

count(): Parameter must be an array or an object that implements Countable (laravel getting error)

I want to enter an multiple field entered data in table with for loop
but i am getting an error in the post method.
error is
count(): Parameter must be an array or an object that implements Countable
controller code :-
$degree = $request->degree;
for($i=0;$i<count($degree);$i++){
$edu = new education;
$edu->degree = $request->degree[i];
$edu->clg = $request->clg[i];
$edu->yoc = $request->yoc[i];
$edu->save();
}
so, please suggest me what i can do.
Here not at all big problem,
you can not use count for the one value the array is required for
that i think that you have not been enterd dynamically many values it can be 0
so replace code in your controller:-
$degree = $request->degree;
if($degree > 0)
{
for($i=0;$i<count($degree);$i++){
$edu = new education;
$edu->degree = $request->degree[i];
$edu->clg = $request->clg[i];
$edu->yoc = $request->yoc[i];
$edu->save();
}
}
here i have used $degree if its value is greater then 0 that means
if it has value count grater then one then you can only go for loop and add value to database
otherwise it will be not go in for loop

How can I make this function take dynamic values?

I have created a function to test a input field, the function currently accepts 6 inputs, 3 of them are text to be typed and the other 3 are error messages that we get when certain text is typed, this works fine. The function will loop depending on the number of texts entered, so in this case it will enter text and then click submit and then check error message. It will do this 3 times because I am passing in 3 text values. However I want to be able to make it dynamic so that it can take any number values and loop according to however many are passed.
Cypress.Commands.add('checkErrMsg', (fieldText1, fieldText2, fieldText3, errorText1,errorText2, errorText3) => {
var fieldValues = [fieldText1, fieldText2, fieldText3];
var errorValues = [errorText1, errorText2, errorText3];
var sum =0;
fieldValues.forEach(function(entry) {
cy.get('.textBox').clear().type(entry)
cy.get('.addBtn').click()
cy.get('#errMsg').should('be.visible').and('have.contain',(errorValues[sum++])).click();
});
})
I add the custom command to namespace as required by typescript project in cyprss.
declare namespace Cypress {
interface Chainable {
checkErrMsg(fieldText1: string, fieldText2: string, fieldText3:string, errorText1:string
,errorText2: string, errorText3:string): Chainable<string>;
}
}
The best way to make this kind of variadic function is with a rest parameter. The tricky part is that you need two - one for the fields, one for the errors - if you have each of them as a separate argument. One option is a [string, string] tuple type for each pair of field and error. The declaration would look like this:
declare namespace Cypress {
type FieldAndErrorValues = [string, string];
interface Chainable {
checkErrMsg(...fieldAndErrorValues: FieldAndErrorValues[]): Chainable<string>;
}
}
And the implementation:
Cypress.Commands.add('checkErrMsg', (...fieldAndErrorValues: Cypress.FieldAndErrorValues[]) => {
fieldAndErrorValues.forEach(function([fieldValue, errorValue]) {
cy.get('.textBox').clear().type(fieldValue);
cy.get('.addBtn').click();
cy.get('#errMsg').should('be.visible').and('have.contain',(errorValue)).click();
});
});
And a possible invocation:
cy.checkErrMsg(['field1', 'error1'], ['field2', 'error2']);

Defining Kendo UI Grid Column Templates with a Function that returns a string

I need to create a Kendo UI for jQuery column which uses a function to determine the template. Essentially the data I am receiving from the backend gives me a number, and I need to match up that number to the corresponding entry in another database table. Once the match is found, I need to set the column template to show that entry.
template: function (e) {
countryData.forEach(function (country) {
let countryDesc;
if (country.countryCode == e.countryCode) {
countryDesc = country.description;
return countryDesc;
}
})
}
This is the function that I have written. countryData is an array of JSON objects containing a list of countries with codes, I am matching that code up with e.countryCode to get the correct country. This is then assigned to countryDesc, and returned.
When ran, the columns are just displayed as 'undefined'. I'm confused as to why this isn't working, as if I do this for example: template: "foo", the column would display foo. Surely all i'm doing is returning a string, so this should work?
So after trying loads of things, replacing the .forEach with a plain for fixed this issue.
template: function (e) {
let country;
for (i = 0; i < countryData.length; i++) {
if (countryData[i].countryCode == e.countryCode) {
country = countryData[i].description;
}
return country;
}

The value of one input is affecting another

I have a simple app which allows someone to add a numbers into an input, and have those numbers render onto the page (as inputs) which can be edited.
addSiblingValue(evt) {
this.setState({
currentObject: {
...this.state.currentObject,
numberOfSiblings: evt.target.value
}
});
add() {
const array = [...this.state.array, this.state.currentObject];
this.setState({
array
});
}
siblingCountChange(rowIndex, event) {
const array = [...this.state.array];
array[rowIndex].numberOfSiblings = event.target.value;
this.setState({ array });
}
So when I add a number it renders a new input with the value set to the number I've just added, but when I go to change that value, it now is affecting the first input.
The first row of inputs are using their own object currentObject which pushes to to the this.state.array, so I'm not sure why editing anything in that array would affect the currentObject?
Expected behaviour:
User enters a number into the input and clicks add
That input is rendered and can be edited independently
How do I achieve this or what is it I'm doing wrong here?
CodeSandbox
Thank you
When you add this.state.currentObject to the array, it works as an reference, so that the added object in the array and this.state.currentObject are the same object. You can prevent that by adding not the object itself, but a copy of the object into the array:
add() {
const array = [...this.state.array, {"numberOfSiblings": this.state.currentObject.numberOfSiblings}];
this.setState({
array
});
}
siblingCountChange(rowIndex, event) {
const array = [...this.state.array];
array[rowIndex].numberOfSiblings += parseInt(event.target.value);
this.setState({ array });
}
You were not adding the actual number to the current state. I also removed the value from the add like so:
<input
type="text"
onChange={this.siblingCountChange.bind(this, rowIndex)}
/>
You will need to put error handling on the state as a string plus a number leads to NaN error. As you can see the number is parsed before addition.
Thanks to dieckie for pointing me in the right direction. Unfortunately that particular solution did not work, but using Object.assign to create a reference and pushing that to the array did?
Posting here so it helps others/myself in future:
add() {
let copyOfCurrentObject = Object.assign({}, this.state.currentObject);
const array = [...this.state.array, copyOfCurrentObject];
this.setState({
array
})
}
This question was also helpful.

Vuejs - Assign computed properties to data()

I have an input field that I would like to either be blank or populate depending on the condition
Condition A: new student, blank field
Condition B: existing student, populated field
This data is coming from the data() function or a computed: property. For example:
data () {
return {
studentName: '', // empty student name property (/new student route)
studentPersonality: ''
}
},
computed: {
...mapGetters({
getStudent // existing student object (/edit student route)
})
}
My input field should either be blank if we are arriving from the /new student route, or populate the field with the existing student info, if we're coming from the /edit route.
I can populate the input field by assigning getStudent.name to v-model as shown below.
<input type="text" v-model="getStudent.name">
...and of course clear the field by instead assigning studentName to v-model
<input ... v-model="studentName">
Challenge: How can I use getStudent.name IF it exists, but fall back on the blank studentName data() property if getStudent.name does NOT exist? I have tried:
<input ... v-model="getStudent.name || studentName">
...which seemed to work, but apparently invalid and caused console errors
'v-model' directives require the attribute value which is valid as LHS
What am I doing wrong?
There's really no need to have the input field register to different properties in your vue component.
If you want to have a computed property that is also settable, you can define it using a set & get method.
computed: {
student_name: {
get: function() {
return this.$store.getters.get_student.name
},
set: function(val) {
this.$store.commit('set_student_name');
}
}
}
One other way is to separate the value from the input change handler in the input element itself, in this case you would use the getter as you've set it
<input type="text" :value="getStudent.name" #input="update_name($event.target.value)">
And lastly, if you need to really use two different properties you can set them on a created/activated hook (and answering your original question):
created: function() {
this.studentName = this.getStudent
},
activated: function() {
this.studentName = this.getStudent
}
You'll always need to delegate the update to the store though so I would either go with the get/set computed property, or the value/update separation

Categories

Resources