Vue 3 Internal server error: v-model cannot be used on a prop, because local prop bindings are not writable - vuejs3

I found this error and blocked my webapps.
2:32:22 PM [vite] Internal server error: v-model cannot be used on a prop, because local prop bindings are not writable.
Use a v-bind binding combined with a v-on listener that emits update:x event instead.
Plugin: vite:vue
File: /Users/julapps/web/myapp/src/components/switch/AudienceTimerSlide.vue
I want to make timer data become data model (editable) and its default value from component props. Why this not work? I'm very new in vuejs, how can i solve this problem? Kindly Please Help...
<template>
----
<div class="field-body">
<div class="field">
<div class="control">
<input #keypress.enter="save" v-model="timer" type="number" class="input is-normal">
</div>
</div>
</div>
-----
</template>
<script>
export default {
props:['id', 'timer'],
setup(props, context){
-----
const save = async() => {
// save form
}
return {
}
}
}
</script>

you have to change defineProps(['question', 'choices'])
to
const props=defineProps(['question', 'choices'])
call as props.question in script like
<TextInput :text="props.question" ></TextInput>

Props are read-only One-Way Data Flow
Use an internal data property with timer as initial value. Like this:
data() {
return {
localTimer: timer
}
}
and
<input #keypress.enter="save" v-model="localTimer" type="number" class="input is-normal">
Or replace v-model with v-bind:value & emit an event
#input="$emit('update:modelValue', $event.target.value)"
Like this:
<input #keypress.enter="save" :value="timer" #input="$emit('update:modelValue', $event.target.value)" type="number" class="input is-normal">

Related

This.data from #each-iteration

I'm trying to access a value inside an {{#each in}}-iteration:
{{#each room in channels}}
<form class="enterRoom">
<button type="submit" class="roomJoin">
<b>{{room.name}}</b>
<img src="{{room.roomBanner}}" alt=".">
<input type="hidden" value="{{room.name}}" name="name">
</button>
<div class="inRoom">
{{#each name in room.inRoom}}
{{name}}
{{/each}}
</div>
</form>
{{/each}}
Normally I would use this.name, for example, to get the name of it inside an event to use it further, like so
'submit .enterRoom'(event) {
event.preventDefault();
const isClosed = this.name; // room.name example here
}
But this doesn't work in this scenario. What I tried before was:
room.name
this.room.name
But those give the same error
chat.js:86 Uncaught ReferenceError: room is not defined
at Object.submit .enterRoom (chat.js:86)
at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3818
at Function.Template._withTemplateInstanceFunc (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3769)
at Blaze.View.<anonymous> (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:3817)
at blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:2617
at Object.Blaze._withCurrentView (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:2271)
at Blaze._DOMRange.<anonymous> (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:2616)
at HTMLFormElement.<anonymous> (blaze.js?hash=51f4a3bdae106610ee48d8eff291f3628713d847:863)
at HTMLDivElement.dispatch (modules.js?hash=8331598f8baf48556a442a64933e9b70b778274a:9685)
at HTMLDivElement.elemData.handle (modules.js?hash=8331598f8baf48556a442a64933e9b70b778274a:9492)
Could someone explain to me how I could do it in this {{each in}}-setting properly?
The error has nothing to do with the each iterations of your template. What you try is to get the form data within the submit event handle. However, there is no context bound to this or room.
In order to get the room value, you need to access the input value.
Blaze offers a fast way of doing so, by using the Template's builtin jQuery (using templateInstance.$), which automatically scopes to the Template root instead of the whole document:
'submit .enterRoom'(event, templateInstance) {
event.preventDefault();
const roomName = templateInstance.$(event.currentTarget).find('input[name="name"]').val();
// ...
}

How do I apply CSS to redux-form fields?

How do I apply any type of CSS to redux-form Field components? className and class are silently ignored:
<div>
<label>Name</label>
<div>
<Field
className="form-input"
name="formContactName"
component="input"
type="text"
placeholder="Person to contact"
/>
</div>
</div>
I was able to the apply the styles by creating a custom component:
<div>
<label>Name</label>
<div>
<Field
name="formContactName"
component={ customInput }
/>
</div>
</div>
but that's a major PITA and also largely negates the gains of using redux-form in the first place. Am I missing something? Note I added the className assignments directly in the custom component - I realize I can send them through as props in Field.
I tried setting input styles globally but they were ignored as well. The redux-form website docs tell you everything you need to know to use the rig but make no mention of CSS that I can see...
Thanks,
JB
Edit: this is not a duplicate - the answer pointed to uses a custom input component. As stated above, I can get that to work, but then there's really no need for redux-form in the first place.
#Jay: I was able to get this to work with a custom component by grabbing the code from the online docs:
class MyCustomInput extends Component {
render() {
const { input: { value, onChange } } = this.props
return (
<div>
<label htmlFor="formContactName" className="col-sm-2 control-label">Name:</label>
<div className="col-sm-10">
<input
id="formContactName"
placeholder="Person to contact"
className="form-control"
type="text"
/>
</div>
</div>
)
}
}
and then, in the redux-form Form code:
<div>
<label>Name</label>
<div>
<Field
name="formContactName"
component={ MyCustomInput }
/>
</div>
</div>
The bootstrap settings via className worked fine using this method.
All your custom props would be passed to the input component, so you can do
const CustomTextField = props => {
const { input, label, type, meta: { touched, error }, ...other } = props
return (
<TextField
label={label}
type={type}
error={!!(touched && error)}
helperText={touched && error}
{ ...input }
{ ...other }
/>
)
}
And then you can pass any props, including className to the CustomTextField
<Field
name="some"
component={CustomTextField}
className="css-applied"
/>

Get user input from textarea

I'm new to angular2. I want to store user input from a text area in a variable in my component so I can apply some logic to this input. I tried ngModel but it doesn't work. My code for the textarea:
<textarea cols="30" rows="4" [(ngModel)] = "str"></textarea>
And inside my component:
str: string;
//some logic on str
But I don't get any value in str inside my component. Is there an error with the way I'm using ngModule ?
<pre>
<input type="text" #titleInput>
<button type="submit" (click) = 'addTodo(titleInput.value)'>Add</button>
</pre>
{
addTodo(title:string) {
console.log(title);
}
}
I think you should not use spaces between the [(ngModel)] the = and the str. Then you should use a button or something like this with a click function and in this function you can use the values of your inputfields.
<input id="str" [(ngModel)]="str"/>
<button (click)="sendValues()">Send</button>
and in your component file
str: string;
sendValues(): void {
//do sth with the str e.g. console.log(this.str);
}
Hope I can help you.
Tested with Angular2 RC2
I tried a code-snippet similar to yours and it works for me ;)
see [(ngModel)] = "str" in my template
If you push the button, the console logs the current content of the textarea-field. Hope it helps
textarea-component.ts
import {Component} from '#angular/core';
#Component({
selector: 'textarea-comp',
template: `
<textarea cols="30" rows="4" [(ngModel)] = "str"></textarea>
<p><button (click)="pushMe()">pushMeToLog</button></p>
`
})
export class TextAreaComponent {
str: string;
pushMe() {
console.log( "TextAreaComponent::str: " + this.str);
}
}
Just in case, instead of [(ngModel)] you can use (input) (is fired when a user writes something in the input <textarea>) or (blur) (is fired when a user leaves the input <textarea>) event,
<textarea cols="30" rows="4" (input)="str = $event.target.value"></textarea>
Here is full component example
import { Component } from '#angular/core';
#Component({
selector: 'app-text-box',
template: `
<h1>Text ({{textValue}})</h1>
<input #textbox type="text" [(ngModel)]="textValue" required>
<button (click)="logText(textbox.value)">Update Log</button>
<button (click)="textValue=''">Clear</button>
<h2>Template Reference Variable</h2>
Type: '{{textbox.type}}', required: '{{textbox.hasAttribute('required')}}',
upper: '{{textbox.value.toUpperCase()}}'
<h2>Log <button (click)="log=''">Clear</button></h2>
<pre>{{log}}</pre>`
})
export class TextComponent {
textValue = 'initial value';
log = '';
logText(value: string): void {
this.log += `Text changed to '${value}'\n`;
}
}
Remove the spaces around your =:
<div>
<input type="text" [(ngModel)]="str" name="str">
</div>
But you need to have the variable named str on back-end, than its should work fine.
If ngModel is used within a form tag, either the name attribute must be set or the form.
control must be defined as 'standalone' in ngModelOptions.
use either of these two:
<textarea [(ngModel)]="person.firstName" name="first"></textarea>
<textarea [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}"></textarea>
it worked for me.

Webform onSubmit not working with more that on input in React

I have a react component in meteor with a webform in. The following code works fine and prints hello addtile in the console:
export default class NewTileForm extends Component {
addTile(event){
event.preventDefault();
console.log("hello addtile")
}
render(){
return(
<div>
<form className="tile-new" onSubmit={this.addTile.bind(this)}>
<input type="text"
ref="tile"
placeholder="Tile Title"/>
</form>
</div>
)
}
}
However, if I try to add a input to the webform I get no response from the console log:
export default class NewTileForm extends Component {
addTile(event){
event.preventDefault();
console.log("hello addtile")
}
render(){
return(
<div>
<form className="tile-new" onSubmit={this.addTile.bind(this)}>
<input type="text"
ref="tile"
placeholder="Tile Title"/>
<input type="text"
ref="company"
placeholder="Tile Company"/>
</form>
</div>
)
}
}
What am I missing?
This is "a browser thing" - you can't submit a form with the enter key and without a submit or button. No it's not react specific. To be honest, not sure why it worked with one - not sure the caveat there.
Anywho, Stackoverflow has lots of answers about tackling this issue (when you remove react as the problem):
Submitting a form by pressing enter without a submit button

React event handlers not binding properly

I am building a React app with Semantic UI in Meteor. I have had two places where event handlers don't seem to be functioning in any capacity, and I haven't found anything online with a problem to the same extent.
Below is my React class. I have tried various ways of calling the eventHandler methods, but nothing works. That also seems irrelevant since I can't even get an anonymous function to run.
SaveSearchPopout = React.createClass({
getInitialState: function() {
return {username: "", queryname: ""};
},
handleUsernameChange:function(e) {
console.log(e.target.value);
this.setState({username: e.target.value})
},
handleQuerynameChange:function(e) {
this.setState({queryname: e.target.value})
},
handleSave:function(e) {
console.log("handling save");console.log(e);
e.preventDefault();
alert("saving!");
return false;
},
render: function() {
console.log(this);
return (
<div className="ui modal saveSearchPopout">
<div className="header">Save Search</div>
<div className="content">
<form className="ui form" onSubmit={function() {console.log("test");}}>
<div className="field">
<input type="text" name="username"
placeholder="Username"
value={this.state.username}
onChange={function() {console.log("update")}} />
</div>
<div className="field">
<input type="text" name="queryname"
placeholder="Name this search"
value={this.state.queryname}
onChange={this.handleQuerynameChange}></input>
</div>
<div className="actions">
<div className="ui cancel button">Cancel</div>
</div>
<button type="submit">Click</button>
<button className="ui button" type="button"
onClick={function() {console.log("saving");}}>Save</button>
</form>
</div>
</div>
);
}
});
The class is rendered from another classes method which looks like:
saveSearch: function() {
var backingDiv = document.createElement('div');
backingDiv.id = 'shadowPopupBack';
document.getElementsByClassName('content-container')[0].appendChild(backingDiv);
ReactDOM.render(<SaveSearchPopout />, backingDiv);
//this.props.saveSearch;
$('.ui.modal.saveSearchPopout')
.modal({
closeable:false,
onDeny: function() {
var container = document.getElementsByClassName('content-container')[0];
var modalContainer = document.getElementById('shadowPopupBack');
container.removeChild(modalContainer);
}
})
.modal('show');
},
The only button that works is the Semantic UI cancel button.
Has anyone else run into this or have any idea what I am missing. Thanks for the help.
Don't know if this is the case, but in newer versions of React (or JSX), when you pass a function to an HTML component or a custom component, that function is not automatically bound to this instance.
You must bind them manually. For example:
onChange={this.handleQuerynameChange.bind(this)}
Or you could use arrow functions, because they will automatically bind to this:
onChange={e => this.handleQuerynameChange(e)}
I eventually found the answer here. Semantic UI modal component onClose with React
and I haven't worked through it yet, but it looks like this is more Reactive solution than using jQuery to bind eventHandlers: http://www.agilityfeat.com/blog/2015/09/using-react-js-and-semantic-ui-to-create-stylish-apps.
Hope this is helpful to someone else.

Resources