I have a text input and send button for submitting the text that I have entered in input field. I have used react-mention library for hashtags. Now when user is entering text and if user type "#" then it shows available hashtags from data. I want to add a functionality, if hashtag is not present in data then I want to add that hashtag dynamically and make api call.
Hashtag data looks like:
const hashtagData = [
{ id: 0, display: "end" },
{ id: 1, display: "start" },
];
Once user has selected the preregistered hashtag and writing his own hashtag, text will look like:
"sample text for already present hashtag #end and manually entered #newHashtag
Inside my onclick function of submit button, I've written this logic for checking newly entered hashtag:
let array = [];
newComment.split(" ").map((word) => {
array.push(word.split("#")[1]);
});
var r = hashtagData.some((i) => i.display.includes(array.map((j) => j)));
console.log(r);
I am not sure if I am doing it right, what is mistake in my code and should I put this logic in onClick or in onChange method?
CodePudding user response:
I don't know if this will help you but here are the some problems I see here
array.map((j) => j)
is same as array
just maps the array to itself
let array = [];
newComment.split(" ").map((word) => {
array.push(word.split("#")[1]);
});
map
is a transformation function but used here to make a loop
If you want to use map
properly then do this
let array = newComment.split(" ").map(word => word.split("#")[1]);
i.display.includes(array.map((j) => j))
display
is a string and array
is an array
You are checking if a string includes an array which doesn't make any sense
I assume what you are trying to do is
hashtagData.some(i => array.includes(i.display))
CodePudding user response:
Assuming .split(" ")
is sufficient for "words" for your purposes, then what you have isn't too far off. Some notes:
- It's misleading to use
map
if you aren't using the array it creates (more in my blog post about it). word.split("#")[1]
will give youundefined
for words that don't have#
in them, which you probably want to weed out.i.display.includes(array.map((j) => j))
doesn't work for a couple of reasons:array.map((j) => j)
is pointless, it just creates a copy of the array.includes
expects a string as its argument, not an array, so will convert the array to a string; that joins together the array entries with commas in-between, which won't match your hashtags.
Instead, something along these lines:
const newTags =
// Split the comment into "words"
newComment.split(" ")
// Get the "words" that are hashtags (or `undefined` for ones that aren't)
.map(word => word.split("#")[1])
// Filter out the "words" that either A) Are `undefined` or B) Are already known
// in `hashtagData`
.filter(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
That gives you an array of the new hashtags in the comment (empty if none).
Live Example:
const hashtagData = [
{ id: 0, display: "end" },
{ id: 1, display: "start" },
];
const newComment = "sample text for already present hashtag #end and manually entered #newHashtag";
const newTags =
// Split the comment into "words"
newComment.split(" ")
// Get the "words" that are hashtags (or `undefined` for ones that aren't)
.map(word => word.split("#")[1])
// Filter out the "words" that either A) Are `undefined` or B) Are already known
// in `hashtagData`
.filter(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
console.log(newTags);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
If you just need a flag instead, use some
instead of filter
at the end:
const hasNewTag =
// Split the comment into "words"
newComment.split(" ")
// Get the "words" that are hashtags (or `undefined` for ones that aren't)
.map(word => word.split("#")[1])
// See if there's any "word" that is both A) Not `undefined`, and B) Not already
// known in `hashtagData`
.some(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
Live Example:
const hashtagData = [
{ id: 0, display: "end" },
{ id: 1, display: "start" },
];
const newComment = "sample text for already present hashtag #end and manually entered #newHashtag";
const hasNewTag =
// Split the comment into "words"
newComment.split(" ")
// Get the "words" that are hashtags (or `undefined` for ones that aren't)
.map(word => word.split("#")[1])
// See if there's any "word" that is both A) Not `undefined`, and B) Not already
// known in `hashtagData`
.some(word => word !== undefined && !hashtagData.some(tag => tag.display === word));
console.log(hasNewTag);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
You should use Regex
Pattern
([^a-z] [a-z]*)*
Select groups