I seem to be having an issue with the vue lifecycle - the global objects that I'm retrieving data in the DOM using something like {{ family.plusOne }} is defined.
When I'm using it as an attribute such as :checked="family.plusOne" //expecting true as value, it's undefined.
I tried running the :check="callFunction()" and logging it to console.
I get two calls, one saying
family.plusOne is undefined
and another log to console saying
family.plusOne being true
which is the value I expected.
<label class="mdl-switch mdl-js-switch mdl-js-ripple-effect" for="switch">
<input type="checkbox" id="switch" #change="setPlusOne($event.target.checked)" class="mdl-switch__input" :checked="(family.plusOne == 1)"/>
<span class="mdl-switch__label" >{{family.plusOne == 1}}</span>
</label>
The {{family.plus ==1 }} within the span displays true but the :checked="(family.plusOne ==1)" is false
First, if you are passing just family.plusOne, what is the result in the child?, undefined?
Secondly, may you can use a computed property like
:checked="computedFamilyPlusOne"
computed: {
computedFamilyPlusOne: {
if(this.family.plusOne == 1){
return true
}else {
return false
}
}
}
My guess is that your family object does not exist as part of the default data binding in the data() {} method that is usually on a Vue.js component. That would mean that before the component is mounted, Vue doesn't know the value when it compiles the template, so it appears as though the value is undefined. Then, at some point, you are probably updating ONLY that property of the family object. This means that the reactive-state of the object has never changed, so Vue.js doesn't know that it needs to recompute the template (reactive "gotcha").
To verify that I am correct, make sure that you use the Vue.set() method, or re-bind a new object with the updated property value for the family object.
I played around with the lifecycle phases
created() {
this.populatePeople();
},
updated() {
componentHandler.upgradeDom();
},
This allowed me to update the data before the DOM was loaded and following some solutions, I call componentHandler.upgradeDom() to show the switches and radio buttons correctly.
Related
Hi I'm working on a simple address book app made with ReactJS.
There's one boolean key in state called 'show_personal'. By default it is set to false. When it is true then the component will render personal address book.
For some reason this boolean value keeps changing on page reload. I've put some logging statements which shows value of it.
I noticed that almost in a sec when the component gets rendered, its value changes due to which my component get re-rendered and this breaks my app UI.
I'm using proper way to update state using this.setState method. While logging/debug I've disabled every possible function which toggles this value. Still facing this issue
Is there anyway to trace which component of code has changed it's value ?
class Home extends React.Component{
state = {
show_personal : false
}
render(){
const checkFlag = ()=>{
if(this.state.show_personal){
return <div>Show personal records</div>
}
}
else{
return <div>Show business records</div>
}
return({
{checkFlag}
})
}
}
Hi your render syntax is a little unusual, you return your checkFlag function without calling it, I don't known what that could do...
Maybe you could try it like this to see if it behaves better
class Home extends React.Component{
state = {
show_personal : false
}
render() {
return this.state.show_personal ? <div>Show personal records</div> :
<div>Show business records</div>
}
}
I am struggling to pull through the api to the front end. I completed it successfully with
https://jsonplaceholder.typicode.com/ Just mapped out the arrays. i am struggling however to pull through this seperate api I wanted to use
https://gateway.marvel.com/v1/public/comics?apikey=xxxxxxxxxxxxxxxx&ts=redant&hash=140e85a50884cef76d614f6dacada288
the erro is..
"Uncaught TypeError: Cannot read properties of undefined (reading 'results')"
so clearly it isnt actually able to get hold of results
What am I doing wrong?
import React, {Component} from 'react';
import './App.css';
class App extends Component {
constructor() {
super();
this.state = {
list: []
};
}
componentDidMount() {
fetch('https://gateway.marvel.com/v1/public/comics?apikey=3cb62d086d5debdeea139095cbb07fe4&ts=redant&hash=140e85a50884cef76d614f6dacada288')
.then (response => response.json())
.then(users => this.setState({list:users}))
}
render() {
return (
<div className='App'>
{
this.state.list.data.results.map(result =>
<h1 key={result.id}>{result.urls}</h1>
)
}
</div>
)
}
}
export default App
The error Uncaught TypeError: Cannot read properties of undefined (reading 'results') in your code means that this.state.list.data returns as undefined. This means that you'll need to focus on your state property list to ensure that it has a data property. As we see in your constructor, data is initialized to an empty array which does not contain the data property.
Something we can do to prevent the error is to surround your code with an undefined check:
if (this.state.list.data != undefined) {
this.state.list.data.results.map(result =>
<h1 key={result.id}>{result.urls}</h1>
)
}
At this point, though, we don't know if your API call is returning good data or not since your program throws the error before that (since the fetch and setState are asynchronous), so the code above mainly addresses the error that you're getting rather than focusing on the "pull through the api to the front end" portion of your question.
Here's what you can do inside your then part after fetching the results
this.setState({list:users.data.results}
And inside the map function, do the following:
this.state.list.map(result =>
<h1 key={result.id}>{result.urls}</h1>
You are getting an error because List is initially empty it doesn't have any key called as results, once you fetch the result only then can you loop through your result.
Another solution would be to simply add a loader, you can control that via state as well.
https://github.com/dongha1992/MERN-boilerplate
enter image description here
hello. currently I tried to practice shopping mall clone as react and node.js
I faced that problem I attached. it doesn't seem that error for cos I copied same as tutorial but it is something wrong with node.js(localhost:5000)
I tried to everything to fix it but don't know how to approach. please help me!
enter image description here
Probably an asynchronous request that populates your props.images hasn't returned a response.
Prefix props.images && to props.images.map function
That way only when the prop is present does the the map occur. Like this
{props.images && props.image.map(image=>.........
Ok, this is often an issue of a variable taking on different value during code execution. To safeguard again this, it's recommended to make sure that the props or a specific variable is defined before it's used.
// alternative-1
function ImageSlider(props){
return props.images && (
<div>
<Carousel autoplay>
{props.images.map((image, index) =>
// ...
)}
// ...
</div>
);
};
OR
// alternative-2
function ImageSlider(props){
return props.images ? (
<div>
<Carousel autoplay>
{props.images.map((image, index) =>
// ...
)}
// ...
</div>
) : null;
};
Critically, here's what is happening in the return() statement.
Alternative-1 (Implicit):
The second part, <div> is only rendered if the first part is true.
In core JavaScript, undefined is equivalent to false so props.images is true only when images is !undefined (not undefined; in other words, images is defined).
Alternative-2 (Explicit):
This one is more direct, as long as props.image is undefined, we return null.(Remember, a valid react component must return something. If nothing, then return null)
Only when props.images is defined, then we return the <div>.
These added checks ensure that your code never breaks, in this case your map() will always be called on a defined variable (props.images).
Here's a good read on Conditional rendering from the react team.
It looks like you're trying to call the map function on data that hasn't been received from your axios request. You should add some logic so that any components that rely on your request data render only if it exits, easily done with a ternary operator.
It looks like many components (including imageSlider) depend on data you try to access when you call your renderCards function on line 54 of your App.
Having trouble in setting up the default value for the drop down when AngularJS/ng-repeat/custom directive + Select2 JS is used.
1. I avoided using ng-options as the directive priority is 0.
2. I tried setting the priority for the custom directive 'select2Directive' to a number less than 1000, but still no luck.
Plunker # http://plnkr.co/edit/Csy5FqDSQbErTm2fNPac. Appreciate any help. Thanks.
I noticed that you are calling the select2 using a small directive, but I found this library named angular-select2 which is easy to implement as well.
you can set the default values with your ng-model/$scope, take a lookt to this plunker to get the idea
http://plnkr.co/edit/pFkY5f?p=preview
EDIT:
I'd rather try to pass the data in other way seems like the select2 data and your the ng-repeat are not in sync
you could try a different approach something like creating a directive and insert the data from there.
directive('select2Dynamic', function ($timeout) {
return {
restrict: 'A',
priority: 1,
scope: {
ngModel: "="
},
require: 'ngModel',
link: function (scope, element, attr) {
var select2Inst = element.select2();
select2Inst.select2({data:scope.$parent.$eval(attr.ngModel)});
select2Inst.select2('val',attr['select2Dynamic']);
}
}
});
<select select2-dynamic='2' ng-model='addresses' id="address" name="address" style="width:200px;" >
</select>
if you want to stick to your approach you'll consider to set up the value and the end of the "model binding event"
look at this plunker
anyway I still stand my point that you should try angular-select2 library
hope that helps
I have an input field that I am trying to add custom validation to (required depending on another field). If I put required AND funcCall() I can see that two errors are returned. If I only put the funcCall nothing is returned. I know it's getting in the function and the condition because I did a console.log() but for some reason it seems like it needs an initial rule to fail to show the error.
Call:
<input type="text" class="validate[funcCall[validatePassportRequired]]" id="form_register_passport_number" value="" name="passport_number" size="50">
Function:
function validatePassportRequired(field, rules, i, options) {
if ($('#register_for').val()!='Local') {
return options.allrules.required.alertText;
}
}
So If I change the Call to:
class="validate[required, funcCall[validatePassportRequired]]"
I get two * This field is required
Do I have to have another validation rule along with the funcCall?
just add the following line before returning the error message and instead of required in returning message put the function name before .alertText.
rules.push('required');
#sunzyflower in your case your function would see like this..
function validatePassportRequired(field, rules, i, options) {
if ($('#register_for').val()!='Local') {
rules.push('required');
return options.allrules.validatePassportRequired.alertText;
}
}
Use
funcCallRequired[validatePassportRequired]
instead of
funcCall[validatePassportRequired]
This will add required internally without having a double message.
If you want more information about the (old) issue :
https://github.com/posabsolute/jQuery-Validation-Engine/issues/392
https://github.com/posabsolute/jQuery-Validation-Engine/pull/785