I am using a text area with Vue v-model and saving it in a firestore collection. But the line breaks disappear in database.
How can it be fixed ?
<div class="form-group">
<textarea v-model="docsInfo" rows="3"></textarea>
</div>
// ... JS
export default {
data() {
return {
title: "",
docsInfo: "",
};
},
// ...
db
.collection("posts")
.add({
title: this.title,
info: this.docsInfo // from text area
})
The line breaks don't appear in Firestore console and the text is shown as a single line, but they are saved.
Just apply the marked answer in the link below.
Vue.js show white space (line breaks)
Related
How can I make a selection with images and have the image get selected too
<v2-select :options="books" label="url">
<template #option="{url}">
<img :src="url">
</template>
</v2-select>
books: [
{
url: 'https://codeclimate.com/github/sagalbot/vue-select'
}
],
I need the title to be the clicked image
in doc i find https://vue-select.org/api/slots.html#selected-option
But I don't know how to put it together.
I'm making a little React app where a user tries to guess a scrambled word on the screen. I'm fetching random words from an external API, but each word has a different length. Instead of a normal input, I want a box-like input where a box is rendered for each letter in the word. Since the word is of dynamic size and not static, I'm having trouble styling my input to get the desired result. For example, for the word "alphabets" which has 9 letters, I would want to render the following input:
where each grey box represents a single character, and as you type, the letter you guess would fill in the box. My current code using a regular input:
const WordGuess = ({ word }) => { // word is fetched in App.js and passed down as a prop
const [isInputDisabled, setIsInputDisabled] = useState(false);
const [userGuess, setUserGuess] = useState('');
// disabling the input when the user guesses the correct word
useEffect(() => {
if (word) {
setIsInputDisabled(userGuess === word ? true : false);
}
}, [userGuess]);
return (
<div>
<input value={userGuess}
onChange={e => setUserGuess(e.target.value)}
disabled={isInputDisabled}
/>
{isInputDisabled && (
<div><p>You guessed correctly!</div>
)}
</div>
)
})
export default UserGuess;
I want to display Flags icons inside a React Bootstrap selection Option. I have tried both CSS based and React based libraries to do so and in each case I get only [object object]
I have tried with the https://github.com/lipis/flag-icon-css CSS library
<Form.Control as="select">
<option><span className="flag-icon flag-icon-gr"></span></option>
</Form.Control>
Which gives me a warning and the same [Object object]
Warning: Only strings and numbers are supported as <option> children.
I have also attempted with the React wrapper for the same library https://www.npmjs.com/package/react-flag-icon-css
<Form.Control as="select">
<option><FlagIcon className="countryIcon" code="us" size="lg"/></option>
</Form.Control>
Which does not generate a warning but no results either
Does anyone know how I can get something else than string or number in the Option, or another way to include an icon ?
Option HTML tag accepts text only, it can't accept any other HTML, it will strip it. You can check this React issue [bug][16.5.0] option returns [object Object] instead of string and read the comment by Dan Abramov:
I don't think it was strictly a regression. This is kind of a thorny
area. It was never intentionally supported. It accidentally worked on
initial mount but then crashed on updates (#13261). Fixing the crash
was more important, so we fixed it to be treated as text content
(which it should be). Unfortunately this means putting custom
components in the middle is not supported. That's consistent with how
textarea and similar elements work.
I think it's better to show invalid output and warn about something
that breaks on updates, than to let people use it only to discover it
crashes in production. But I can see arguments for why this should be
supported when the custom component returns a string. Unfortunately I
don't know how to fix it in a way that would both solve the update
crashes and support text-only content. I think for now it's reasonable
to say putting custom components into doesn't really work
(and never quite worked correctly), and ask you to manually provide a
string to it.
Alternatively, you can use Bootstrap Dropdowns to create a dropdown button with a list of countries using the code below:
App.js:
...
import Dropdown from 'react-bootstrap/Dropdown';
import FlagIcon from './FlagIcon.js'
function App() {
const [countries] = useState([
{ code: 'gr', title: 'Greece'},
{ code: 'gb', title: 'United Kingdom'},
{ code: 'us', title: 'United States'}
]);
const [toggleContents, setToggleContents] = useState("Select a country");
const [selectedCountry, setSelectedCountry] = useState();
return (
<div className="App">
<Form>
<Dropdown
onSelect={eventKey => {
const { code, title } = countries.find(({ code }) => eventKey === code);
setSelectedCountry(eventKey);
setToggleContents(<><FlagIcon code={code}/> {title}</>);
}}
>
<Dropdown.Toggle variant="secondary" id="dropdown-flags" className="text-left" style={{ width: 300 }}>
{toggleContents}
</Dropdown.Toggle>
<Dropdown.Menu>
{countries.map(({ code, title }) => (
<Dropdown.Item key={code} eventKey={code}><FlagIcon code={code}/> {title}</Dropdown.Item>
))}
</Dropdown.Menu>
</Dropdown>
</Form>
</div>
);
}
FlagIcon.js:
import React from 'react';
import FlagIconFactory from 'react-flag-icon-css';
// const FlagIcon = FlagIconFactory(React);
// If you are not using css modules, write the following:
const FlagIcon = FlagIconFactory(React, { useCssModules: false })
export default FlagIcon;
You'll get a dropdown button like this:
You can also check this working Stackblitz: https://stackblitz.com/edit/react-bootstrap-flags-dropdown-menu
Are you closing the tag
<Form.Control as="select">
[object Object] is displayed e.g when you are concatenating a string with an object, for example:
console.log(""+{})
my title question maybe duplicated but, I think its different :D..
I want to update array in firestore ... first time it work ,the second time will
give me this
warning: virtualizedlist: missing keys for items
and give me this error: collectionRferece.doc() required its first argument to be of not empty string but was undefined
I explained my code step by step.
Home.js
I receive data from firestore and i send it as a prop to projectList
render(){
const {projects,auth}=this.props;
return(
<ProjectList projects={projects} />
)
}
}
const mapStateToProps=(state)=>{
return{
projects:state.firestore.ordered.projects,
}
}
export default compose(connect(mapStateToProps),firestoreConnect([{collection:'projects',orderBy:['createdAt','desc']}])) (Feed);
ProjectList.js
there is just a flat list and sending data as a prop to projectsummery
const ProjectList =({projects})=> {
return(
<FlatList
data={projects}
refreshing={true}
renderItem={(project)=>{
return(
<ProjectSummery project={project} key={project.item.id}
keyExtractor={(item, index) => item.item.id}
/>
)
} }
/>
)
}
ProjectSummery.Js
there is some design and button, when i press the button i send project.item.id which is a (doc id) in firestore to project actions.js there is likePosts function which is update the array in firestore
import {likePosts} from '../Store/Actions/ProjectActions'
const ProjectSummery =(props)=> {
const {project,auth}=props
console.log(project.item.id);
return(
<>
<Container style={{flex:0,height:180}} >
<Content >
<Card>
<CardItem>
<Left>
<Button transparent onPress={()=>props.likePosts(project.item.id)}>
<Text>{project.item.likes.length} Likes</Text>
</Button>
</Left>
</Card>
</Content>
</Container>
</>
)
}
const mapDispatchToProps=(dispatch)=>{
return{
likePosts:(postId)=>dispatch(likePosts(postId))
}
}
export default connect(null,mapDispatchToProps)(ProjectSummery);
Actions.js
here i have likePosts fuction which update the array in firestore,
the fist time it works but the second time (project.item.id) postId will be undefined and i have no idea what's going on :D
export const likePosts =(postId)=>{
return (dispatch,getState,{getFirebase,getFirestore})=>{
const profile=getState().firebase.profile
const authId=getState().firebase.auth.uid
const firestore=getFirestore()
console.log(postId);
firestore.collection('projects').doc(postId).update({
likes:firestore.FieldValue.arrayUnion({
likedAt:new Date(),
likedBy: authId,
name: profile.firstName + profile.lastName
})
})
}}
Just in case anyone ends up on this question facing a similar issue, there is this SO question that appears to be different but the issue is caused by the same reason.
Check my answer there and the comments in under the question itself.
In addition to that, you can also check the Pagination section of this article for more guidance.
Original Answer:
What's happening is that when you click a like button the first time, it's working as expected so it gets the proper postId and then continues with the process you have defined. However, when you try the 2nd time it fails to fetch the postId as it's already liked.
The idea is that you'll need to either define an if statement and specify what should happen if it's already clicked and it get's clicked again (possibly storing the postId somewhere the first time and using it from there), or make an initial check that returns a specific message to the user if it's already clicked.
The issue has nothing to do with Firestore itself but with the button and the states of liked/unliked.
Here is one nice interactive example on codepen.io of a proper way of building like buttons using react. React Like Button
HTML
<div id="example"></div>
CSS
.btn-primary {
background-color: #23aa4e;
border-color: #177d37;
}
#example {
margin: 3rem;
}
.customContainer {
border: 1px solid black;
}
JS
class LikeButton extends React.Component {
constructor() {
super();
this.state = {
liked: false
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
liked: !this.state.liked
});
}
render() {
const text = this.state.liked ? 'liked' : 'haven\'t liked';
const label = this.state.liked ? 'Unlike' : 'Like'
return (
<div className="customContainer">
<button className="btn btn-primary" onClick={this.handleClick}>
{label}</button>
<p>
you {text} this. Click to toggle.
</p>
</div>
);
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
)
I am trying to customize the behavior of an editor button in a plugin. On click, it opens a modal where the user can input some text. On confirmation, I want to wrap this text into code tags. But I don't want to take this text as if it comes from a text editor, I want to handle it as visual text. This means, I want to preserve any formatting (whitespaces and linebreaks) but not accept any other tags besides the code tags that I add afterward.
function showDialog() {
var win = ed.windowManager.open({
title: "Insert code",
body: {
type: 'textbox',
name: 'code',
multiline: true,
minWidth: ed.getParam("code_dialog_width", 600),
minHeight: ed.getParam("code_dialog_height", Math.min(tinymce.DOM.getViewPort().h - 200, 500)),
spellcheck: false,
style: 'direction: ltr; text-align: left'
},
onSubmit: function(e) {
ed.focus();
ed.undoManager.transact(function() {
ed.insertContent('<code>' + e.data.code + '</code>');
});
ed.selection.setCursorLocation();
ed.nodeChanged();
}
});
}
First i'd wrap that function in tags and make sure to initiate the function by adding showDialog() at the end of that function so the DOM knows to call the function. and with wordpress's content filter its going to add spaces no matter what unless you disable the content filter from auto populating format. if you go to a site like https://www.willpeavy.com/minifier/ and copy your code into that and minify the spaces you should be able to include it in your text(not Visual) tab in MCE. That being said its really bad practice to run functional code in MCE you're better off making a separate page / Post template for it.