React Select Control - reactjs

I have data in a file named GlobalState.js and I am trying to access it another file named AddClass.js.
GlobalState.js
myclasses:[
{
"id":"class1",
"name":"Maths",
"students":["arun1","ashok1","rajesh1","mahesh1"],
"teachers":["ramesh1","suresh1","ashwin1"]
},
{
"id":"class2",
"name":"Science",
"students":["arun2","ashok2","rajesh2","mahesh2"],
"teachers":["ramesh2","suresh2","ashwin2"]
}
]
I want the students names to be shown on my React-Select control. Below is the code that I tried. Thank you for the support.
AddClass.js
import React, {useState, useEffect, useContext } from 'react'
import { GlobalContext } from '../../context/GlobalState'
import { v4 as uuid } from "uuid";
import { useForm } from "react-hook-form";
import { Link, useHistory } from 'react-router-dom';
import Select from 'react-select'
const AddClass = () => {
const [selectedOption, setSelectedOption] = React.useState();
const { addClass, myclasses} = useContext(GlobalContext);
const studOptions = myclasses.map((c)=> {
return {label:c.students.map((s)=>{
console.log("s",s)
return([{value: s, label:s}]);
}), value:c.id}
})
return (
<React.Fragment>
<form onSubmit={handleSubmit(onSubmit)}>
<label>Select Students</label>
<Select
value={selectedOption}
isMulti
onChange={handleChange}
options={filteredStud}
/>
</form>
</React.Fragment>
)
}
export default AddClass

To get all the students in all classes and put them to one select options, your code should do something like below:
const options = myclasses.map(c => c.students).flat().map(s => ({ label: s, value: s}))

I would make studOptions a state, extract data from myclasses to populate into studOptions, then display it into the select.
Sample: https://codesandbox.io/s/affectionate-liskov-5k6l4?file=/src/App.js

Related

React - Building a form to edit an existing product. Field contents are empty

I successfully built a form to create and save new products. Now I'm working on the page to modify previously created products. I can tell my API is returning data because the title shows up. However, it seems like the form is rendering before the state is populated and therefore the field is empty.
I think that the title is working because it's not reading from the state, it's reading directly from the product.name value which was returned from my API. However, for my form, I believe I need to point my field to the state which is empty at the moment the component rendered.
I'm just not sure how to only render the form once the API is done loading data and state is populated?
Any help greatly appreciated, have been trying to figure this out off and on for months.
I'm using redux toolkit: https://redux-toolkit.js.org/rtk-query/usage/queries#frequently-used-query-hook-return-values
import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import { useParams } from 'react-router';
import { useNavigate } from 'react-router-dom'
import AHeaderNav from '../../../../components/settings/AHeaderNav/AHeaderNav'
import './AdminProductEdit.scss';
import Wysiwyg from '../../../../components/global/Wysiwyg/Wysiwyg';
import SelectInput from '../../../../components/global/SelectInput/SelectInput'
import Breadcrumbs from '../../../../components/global/breadCrumbs/breadCrumbs';
import AdminBackButton from '../../../../components/settings/AdminBackButton/AdminBackButton'
import ImageC from '../../../../components/global/ImageC';
import { useGetProductAuthQuery, useUpdateProductMutation } from '../../../../api/apiSlice';
import { Spinner } from '../../../../components/global/Spinner/Spinner';
const AdminProductEdit = () => {
const { id: productId } = useParams()
const {
data: product = {},
isFetching,
isSuccess,
isLoadingCurrentPoduct } = useGetProductAuthQuery(productId, {
//pollingInterval: 3000,
refetchOnMountOrArgChange: true,
skip: false
})
const [updateProduct, { isLoading }] = useUpdateProductMutation()
const [productName, setProductName] = useState(product.productName)
const navigate = useNavigate()
const onProductNameChanged = e => setProductName(e.target.value)
if(!isSuccess) {
return <Spinner text="Loading..." />
} else {
const canSave = [productName].every(Boolean) && isSuccess && typeof productId === 'number'
const onSaveProductClicked = async () => {
if(canSave) {
try {
await updateProduct({productId,
productName,
productDescription,
productCategory,
shopNowUrl,
assetDescription})
navigate(`../settings/products`)
} catch (err) {
console.error(err)
}
}
}
return (
<div>
<AHeaderNav/>
<div className="topBannerImage">
<ImageC imageSrc={product.assetUrl}/>
</div>
<div className="contentWrapper">
<h3>Editting '{product.productName}'</h3>
<label>
Product Name
<input
type="text"
name="productName"
value={[productName]} // this is rendering an empty field.
// To me it seems like since this portion of the page is only
// supposed to be rendered once the API is successful, then
// this should be populated? What am I missing?
onChange={onProductNameChanged}
disabled={isLoading}
/>
</label>
<div className="button-group align-spaced">
<AdminBackButton/>
<button
className="submit button"
onClick={onSaveProductClicked}
disabled={!canSave}
>Save changes</button>
</div>
</div>
{spinner}
</div>
)
}
}
export default AdminProductEdit;

React.js - CodeMirror: add a keyword to SQLDialect

my react component:
import React, { useState } from "react";
import { sql, SQLConfig, StandardSQL } from "#codemirror/lang-sql";
import CodeMirror from "#uiw/react-codemirror";
function SQLEditor() {
const config: SQLConfig = {
dialect: StandardSQL,
upperCaseKeywords: true,
};
const [command, setCommand] = useState("");
return (
<>
<CodeMirror
value={command}
extensions={[sql(config)]}
onChange={(value) => {
setCommand(value);
}}
/>
</>
);
}
export default SQLEditor;
i'm using #uiw/react-codemirror and #codemirror/lang-sql
let's say i want to add "hello" as a keyword, the same way "INSERT" and "CREATE" are keywords, so that when the user writes "hello" it will get highlighted as a keyword
how can i achieve that?

React js export a variable

I want to receive a value from my variable(meta) in the file form.js
this one:
export const TextInput = ({ icon, ...props }) => {
const [field, meta] = useField(props);
const [showpass, setShowpass] = useState(false);
const [showPopup, setShowPopup] = useState(false);
{'....'}
And I wanto to send it to the file login.js
// styled components
import {
StyledTextInput,
StyledFormArea,
StyledFormButton,
StyledLabel,
Avatar,
StyledTitle,
colors,
ButtonGroup,
ExtraText,
TextLink,
CopyrightText,
ErrorMsg
} from "../components/Styles";
import Logo from "./../assets/logo.png";
// formik
import { Formik, Form,useField } from "formik";
import {TextInput} from "../components/FormLib";
import * as Yup from "yup";
//icons
import { FiMail, FiLock } from "react-icons/fi";
// Loader
import Loader from "react-loader-spinner";
// auth & redux
import { connect } from "react-redux";
import { loginUser } from "../auth/actions/userActions";
import { useHistory } from "react-router-dom";
import AuthCode from 'react-auth-code-input';
import React, { useState } from 'react';
//pop up style.css
import '../assets/css/popup.css'
// Import popup lib
import Popup from "reactjs-popup";
import 'reactjs-popup/dist/index.css';
const Login = ({ loginUser}) => {
const history = useHistory();
const [showPopup, setShowPopup] = useState(false);
{......}
I know it may be a begginner question, but im not being able to figure out how to send this variable through files , by now thanks for the support
Some part of the login file where i want to check the variable
useEffect(() => {
if(meta.error === 'codigo 2 fatores incorreto'){
setShowPopup(true);
}
}, [meta.error])
As you can see I want to handle an pop up in the page login , but I need to get the meta variable to do this
you can create the onMetaChange property then use useEffect hook to pass the meta to the login form whenever meta is changed
like below
export const TextInput = ({onMetaChange, ...props}) => {
const [field, meta] = useField()
...
useEffect(() => {
onMetaChange && onMetaChange(meta);
}, [meta])
...
}
also note that this is not the best practice for doing this you can check code samples from the library you are using to find out what is the best practice and best style

Creating default chat groups in Sendbird using React

We've integrated a chat UI into a project using Sendbird. The chat interface is now working and what I am trying to do now is implement a feature where there are 2 default chat groups as shown in the mockup below:
I have already gone through the docs but I can’t seem to find the information I need to implement this feature. Can this be implemented? can someone guide me to the right direction, please?
import React, { useEffect, useState, useRef } from 'react';
import { useHistory } from 'react-router-dom';
import { useSelector } from 'react-redux';
import 'sendbird-uikit/dist/index.css';
import { App as SendBirdApp, } from 'sendbird-uikit';
import { getModuleState as getAuthModuleState } from 'services/auth';
import colorSet from './styled/chatPalette';
import { Chat, ChatContainer, List } from './styled/chatPage';
import ChatGroups from './ChatGroups';
function ChatPage(props) {
const { theme } = props;
const history = useHistory();
const authState = useSelector(getAuthModuleState);
const userId = authState.username;
const nickname = authState.username;
const appId = authState.sendbirdData.appId;
const accessToken = authState.sendbirdData.accessToken;
useEffect(() => {
if (!userId || !nickname) {
console.error('Error, empty userId or nickname');
}
}, [userId, nickname, history]);
return (
<ChatContainer>
<SendBirdApp
appId={appId}
userId={userId}
nickname={nickname}
colorSet={colorSet}
/>
</ChatContainer>
);
}
export default ChatPage;
you can use the <SendbirdProvider> component and provide your custom channel preview component (let's say <ChannelPreview>) inside the <ChannelList> component.
Within your custom preview component (<ChannelPreview>) you can choose wether or not to show a specific channel based on its member count (channel.memberCount) as shown below:
import { Channel, ChannelList, SendBirdProvider } from 'sendbird-uikit';
import 'sendbird-uikit/dist/index.css';
import { useState } from 'react';
const CHANNEL_PREVIEW_MODES = [
'1-on-1',
'Group'
]
function ChannelPreview({channel, previewMode}) {
if (
(channel.memberCount <=2 && previewMode !== CHANNEL_PREVIEW_MODES[0]) ||
(channel.memberCount > 2 && previewMode !== CHANNEL_PREVIEW_MODES[1])
) {
return null
}
return (
<div key={channel.url}>
<img height="20px" width="20px" src={channel.coverUrl}/>
{channel.url}
</div>
)
}
function App() {
const [previewMode, setPreviewMode] = useState(CHANNEL_PREVIEW_MODES[0])
const [currentChannel, setCurrentChannel] = useState(null);
return (
<div className="App">
<SendBirdProvider
userId='<USER_ID>'
appId='<APP_ID>'
>
<div>
{CHANNEL_PREVIEW_MODES.map(mode =>
<label className="preview-mode-radio">{mode}
<input
type='radio'
value={mode}
name='preview-mode'
onChange={() => setPreviewMode(mode)}
checked={previewMode === mode}
/>
</label>
)}
</div>
<ChannelList
renderChannelPreview={({channel}) => <ChannelPreview channel={channel} previewMode={previewMode} />}
onChannelSelect={channel => setCurrentChannel(channel)}
/>
<Channel channelUrl={currentChannel?.url} />
</SendBirdProvider>
</div>
);
}
export default App;

Why is my search function not being passed?

I am trying to pass a search filter function into my search bar components. But i keep getting this error TypeError: Cannot read property 'search' of undefined
the search function is not recognized my context file is here
https://github.com/CodingOni/Ecommerce-Store/blob/master/src/context.js
import React, { useContext, useEffect, useRef } from 'react';
import ProductContext from '../../src/context';
const ProductFilter = () => {
const productConsumer = useContext(ProductContext);
const text = useRef('');
const { search, searchResults } = productConsumer;
useEffect(() => {
console.log(` product context ${productConsumer}`)
});
const onChange = e => {
if (text.current.value !== '') {
search(e.target.value);
} else {
}
};
return (
<form>
<input
ref={text}
type="text"
placeholder="Search Keywords..."
onChange={onChange}
id=""
/>
</form>
);
};
export default ProductFilter;
useContext accepts a context object (the value returned from
React.createContext) and returns the current context value for that
context.
You pass react component to useContext which is default export from '../../src/context'.
In context file you need export PoductContext
export { ProductProvider, ProductConsumer, ProductContext };
..
import {ProductContext} from '../../src/context';

Resources