Using validate.js to validate my TextInput results in undefined - javascript

I am trying to use validate.js to manage my Textfields validations and after installing validate.js and importing it as import validate from 'validate.js'; then adding it to my InputField it seems that the result is undefined.
I tried to reproduce the issue with Expo snack but the following error appears Device: (953:881) Unable to resolve module 'module://validate.js' here is the Expo link:
https://snack.expo.io/#ahmedsaeed/validatetest
Do I miss something here and is there a better way to validate my form?
Here is my code snippet:
import React, { useState, useEffect } from 'react';
import { View } from 'react-native';
import { HelperText } from 'react-native-paper';
import { InputField } from '../../../GlobalReusableComponents/TextFields';
import validate from 'validate.js';
const SkillsAndExperienceScreen = (props) => {
const [company, setCompany] = useState('');
const constraints = {
company: {
presence: true
}
};
const onCompanyChange = (val) => {
const result = validate({company: val}, constraints);
setCompany(val);
}
return (
<View>
<InputField
onChangeText={(val) => onCompanyChange(val)}
value={company}
placeholder='Company'
/>
</View>
);
}
export default SkillsAndExperienceScreen;
const Style = {
container: {
flex: 1,
backgroundColor: '#f8f9f9'
}
};
Thanks in advance.
Update: It seems that the project is showing me the same error
Unable to resolve module `validate` from `/Projects/Seem/src/screens/CompleteYourProfileScreens/SkillsAndExperienceScreen/index.js`: Module `validate` does not exist in the Haste module map.

Looking at the web, it seems import validate from "validate-js" is the way to go. The npm module is https://www.npmjs.com/package/validate-js. I tried it on your expo snack and it worked. But, i think that's an entirely different module.
There might be an expo snack specific problem on it, prolly the ".js" name perhaps?, not quite sure. I tried installing locally to project of mine and it worked.
I would suggest using https://www.npmjs.com/package/#hapi/joi since it's always has been my go to for object validation and it has much better community support, and updates are more frequent.

Related

GSAP Animations(TweenMax) not triggering in React,

I cannot figure out for the life me what how to get this Gsap animations to work. I'm still learning react but I was able to get everything to work properly in a standard project using html, css, and javascipt but i wanted to try and recreate the effect in React. There's much more code, it'll compile but the animations are kicking in. The error on the console says nothing is wrong and VSCode says nothing is wrong so i'm at a loss. Seems like it should be a simple fix though.
function App() {
// Constants
const leftContainer = document.querySelector('.left-container');
if (leftContainer) {
gsap.from(".left-container", {
duration: 2,
width: '0',
ease: "power3.inOut",
});
}
return (
<>
<div className='containers'>
<div className="left-container">
</div>
</div>
</>
);
};
export default App;
However in a basic HTML it works when I write it as follows...
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>
<script type="text/javascript">
TweenMax.from(".left-container", 2, {
width: "0",
ease: Expo.easeInOut
});
I also tried rewriting everything to follow the modern best practises.
In order to use gsap in react, make sure you have followed these steps:
Create and run basic react app.
npx create-react-app my-app
cd my-app
npm start
Install gsap in the react app using:
npm install gsap
Import the gsap module into the app and use it with the useEffect hook.
import React, { useEffect, useRef } from "react";
import gsap from "gsap";
import "./App.css";
function App() {
const appRef = useRef(); // create a ref for the root level element
useEffect(() => {
let ctx = gsap.context(() => {
// normal selector text, automatically scoped to appRef
gsap.from(".left-container", {
duration: 2,
width: 0,
ease: "power3.inOut",
});
}, appRef);
return () => ctx.revert();
});
return (
<>
<div className="containers" ref={appRef}>
<div className="left-container"></div>
</div>
</>
);
}
export default App;
Here, React will re-run the useEffect() on every render. If you want to avoid that, add empty dependency array.
Like this:
useEffect(() => {
// -- YOUR CODE --
}, []); // <- empty dependency array
Check this documentation for more info: greensock.com/react

window.Calendly.initInlineWidget is not defined on first load but works after refresh with useEffect in React and Gatsby

I am using Gatsby with React and am trying to implement a Calendly booking system. It sort of works. The issue is on first load it gives me the error
TypeError: Cannot read property 'initInlineWidget' of undefined
seen here
If I refresh the page the Calendly Object loads and renders just fine.
I am wondering if there is something I can do in the useEffect to avoid this issue.
import React, { useEffect } from "react"
import Layout from "../components/layout"
const Calendly = styled.div`
height: 800px;
margin-top: 100px;
`
const IndexPage = ({ data }) => {
useEffect(() => {
window.Calendly.initInlineWidget({
url: "https://calendly.com/absolute-hardwood",
parentElement: document.getElementById("bookingjs"),
prefill: {},
utm: {},
})
}, [])
return (
<Layout>
<Calendly id="bookingjs" />
</Layout>
)
}
export default IndexPage
Here is how I am adding the Calendly script in my gatsby-confing.js
{
resolve: "gatsby-plugin-load-script",
options: {
src: "https://assets.calendly.com/assets/external/widget.js",
},
}
Marshall here from Calendly. Since you are using React and Gatsby, you can use the react-calendly package to load the inline embed on your site.
You will need to install the react-calendly package in your project, and then import the InlineWidget like this at the top of your file:
import { InlineWidget } from "react-calendly";
Then, you can use the component on your page:
<InlineWidget url="https://calendly.com/your_scheduling_page" />
I hope this helps! Further documentation can be found in the package readme on Github.

Tests React component with jest and enzyme

i have components presented below. I am totally new in unit testing. Can anyone give any one give me advice how and what should I test in this component? I was trying to shallow render it, to check is text in h2 is present but i still getting errors.
import React, { useEffect } from 'react';
import { Form, Field } from 'react-final-form';
import { useHistory, Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { loginUser, clearErrorMessage } from '../../redux/auth/authActions';
import Input from '../Input/Input';
import ROUTES from '../../routes/routes';
import './LoginForm.scss';
const LoginForm = () => {
const dispatch = useDispatch();
const history = useHistory();
const { loading, isLogged, errorMessage } = useSelector(state => state.auth);
useEffect(() => {
if (isLogged) {
history.push('/');
}
return () => {
dispatch(clearErrorMessage());
};
}, [dispatch, history, isLogged]);
const handleSubmitLoginForm = values => {
if (!loading) {
dispatch(loginUser(values));
}
};
const validate = ({ password }) => {
const errors = {};
if (!password) {
errors.password = 'Enter password!';
}
return errors;
};
return (
<article className="login-form-wrapper">
<h2>SIGN IN</h2>
<Form onSubmit={handleSubmitLoginForm} validate={validate}>
{({ handleSubmit }) => (
<form onSubmit={handleSubmit} autoComplete="off" className="login-form">
<div className="login-form__field">
<Field name="email" component={Input} type="email" label="E-mail" />
</div>
<div className="login-form__buttons">
<button type="submit" className={loading ? 'button-disabled' : ''}>
Sign in
</button>
</div>
</form>
)}
</Form>
</article>
);
};
export default LoginForm;
I am open for any advices :)
First of all, I am not recommending using shallow in your tests and here is a great article why.
I also recommend to check out react-testing-library instead of Enzyme as it is much nicer to use.
Now, to answer your question. You are using here hooks for redux and react-router, so you need to provide the necessary data to your componenent in test so that it can use those hooks. Let me show you an example test (that checks text in h2 element):
import React from 'react';
import { mount } from 'enzyme';
import {Provider} from 'react-redux';
import {MemoryRouter, Route} from 'react-router';
import LoginForm from './LoginForm';
describe('Login Form', () => {
it('should have SIGN IN header', () => {
const store = createStore();
const component = mount(
<Provider store={store}>
<MemoryRouter initialEntries={['/login']}>
<Route path="/:botId" component={LoginForm} />
</MemoryRouter>
</Provider>
)
expect(component.find('h2').text()).toEqual('SIGN IN');
});
});
Some explanation to this example.
I am using mount instead of shallow as I prefer to render as much as possible in my test, so that I can check if everything works together as it should.
You can see that I am not rendering my component directly, but rather it is wrapped with other components (Provider from react-redux and MemoryRouter from react-router). Why? Because I need to provide context to my Component. In this case it's redux and router context so that the data used inside exists and can be found (for example useSelector(state => state.auth) must have some state provided so that it can access auth property). If you remove any of them you would get some error saying that this context is missing - go ahead and check for yourself :).
See here for some details around testing with router context
As for testing with redux in my example there is a createStore function that I didn't define as there are a few approaches to this. One involves creating a real store that you use in your production application. This is the one that I prefer and colleague of mine wrote great article around this topic here. Other is to create some kind of mock store, like in this article. Again, I prefer the first approach, but whichever is better for you.
Answering your other question on what should you test in this example. There are multiple possibilities. It all depends mostly on you business case, but examples that I would test here includes:
Typing something into an input, clicking a button and observing that login is successful (by redirecting to new path - / in this case)
not typing a password and clicking a button - error should be shown
Checking if button class changes when it's loading
Do not dispatch login action twice, when already loading
And so on...
That's really just a tip of an iceberg on what could be written around testing, but I hope it helps and gives you a nice start to dig deeper into the topic.

dynamically import a React Component if that file exists, otherwise show a default message

I want to conditionally import a React Component if the file exists and if not do something else. For example show a default view or message.
I tried this:
let Recipe;
try {
Recipe = require(`docs/app/Recipes/${props.componentName}`);
} catch (e) {
Recipe = () => <div>Not found</div>;
}
However the linter is complaining that I should not try to dynamicaly require a file, but use a string literal instead.
Is there a cleaner approach to to what I'm trying to achieve?
The problem is this approach is that it kills bundle optimizations and includes all files from docs/app/Recipes/ into a bundle, even if they aren't used.
A better way to write this is to use <React.Suspense> and React.lazy:
const Recipe = React.lazy(() =>
import(`docs/app/Recipes/${props.componentName}`)
.catch(() => ({ default: () => <div>Not found</div> }))
);
Which is used as:
<React.Suspense fallback={'loading...'}><Recipe/></React.Suspense>
A cleaner way to do this and avoid linter error is to have a map of possible components:
import Foo from 'docs/app/Recipes/Foo';
import Bar from 'docs/app/Recipes/Bar';
...
const componentsMap = { Foo, Bar };
...
const Recipe = componentsMap[props.componentName] || () => <div>Not found</div>;
In this case props.componentName can be validated if needed.
in fact there is. With the recent release of React v16.6.0 "lazy code splitting" was introduced. This is how it works, it makes sense to use it together with reacts' 'suspense':
import React, {lazy, Suspense} from 'react';
const Recipe = lazy(() =>import(`./docs/app/Recipes/${props.componentName}`));
function SomeComponent() {
return (
<Suspense fallback={<Spinner/>}>
<Recipe />
</Suspense>
);
}
To handle the case that the component isn't found you can use Error Boundaries. You would wrap your component with it like this:
<ErrorBoundary>
<Suspense fallback={<Spinner/>}>
<Recipe />
</Suspense>
</ErrorBoundary>
Best you read more about it directly on the react docs I linked above.
I have been troubled by this problem all afternoon, and now I have solved it:
If "../views/dev/dev.tsx" exists, import it, otherwise import '../views/not-found/not-found'
const requireCustomFile = require.context('../views/dev/', false, /dev.tsx$/);
let Dev = React.lazy(() => import('../views/not-found/not-found'));
if (requireCustomFile.keys()?.length) {
const keys: string[] = requireCustomFile.keys();
if (keys.includes('./dev.tsx')) {
const str = '/dev';
Dev = React.lazy(() => import(`../views/dev${str}`));
}
}
if dev.tsx not exit :
// ⬇️webpack report an error: Can't resolve module
import(`../views/dev/dev.tsx`))
// ⬇️webpack will not report an error until the load the module
const str = '/dev';
import(`../views/dev${str}`)

React Native error: Element type is invalid: expected a string or a class/function but got: object

I am getting this error and I am having a lot of trouble fixing this.
What I am trying to do here is have 3 different screens and have a tabbar that navigates to each screen.
Here is my index:
import React, { Component } from 'react';
import { AppRegistry, Navigator, StyleSheet, View, Text } from 'react-native';
import Nav from './app/components/Nav';
import Screen from './app/Screen';
import Tabs from 'react-native-tabs'
import SwitchView from './SwitchView';
class Proj extends Component {
constructor(props){
super(props);
}
render(){
var x = "FeedView";
return(
<View style={styles.container}>
<Tabs selected={x} style={{backgroundColor:'white'}}
selectedStyle={{color:'red'}} onSelect={el=> {x = el.props.name}}>
<Text name="FeedView">First</Text>
<Text name="WikiView" selectedIconStyle={{borderTopWidth:2,borderTopColor:'red'}}>Second</Text>
<Text name="BoardView">Third</Text>
</Tabs>
<SwitchView id={x}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
})
AppRegistry.registerComponent('Proj', () => Proj);
here is my SwitchView:
import Feed from './app/pages/Feed/Feed';
import Board from './app/pages/Board';
import Wiki from './app/pages/Wiki';
class SwitchView extends Component {
render(){
var { id } = this.props;
switch (id) {
case "FeedView":
return <Feed/>
case "WikiView":
return <Wiki/>
case "BoardView":
return <Board/>
}
}
}
This is probably caused by some JS module export/import issues in your program, typically for one of the two reasons listed below:
You forget to export, or you export something incorrectly
You import something that doesn't exist, or you import something incorrectly
I ran into similar error, but in my case, it is not caused by export but caused by import, and I used the import statement incorrectly to import something that doesn't exist in the module.
In my case, the import was incorrectly written as:
import { MyComponent } from './MyComponents/MyComponent'
while actually it should be:
import MyComponent from './MyComponents/MyComponent'
And it drove me crazy and took me a whole day to figure it out and I hope this will save several hours for some people.
Change your SwitchView definition to
export default class SwitchView extends Component...
Modify your SwitchView to this:
import Feed from './app/pages/Feed/Feed';
import Board from './app/pages/Board';
import Wiki from './app/pages/Wiki';
export default class SwitchView extends Component {
render(){
var { id } = this.props;
switch (id) {
case "FeedView":
return <Feed/>
case "WikiView":
return <Wiki/>
case "BoardView":
return <Board/>
}
}
}
I faced this issue only for the packages installed.
Previously I wrote as
import WebView from 'react-native-webview-messaging/WebView';
I changed to
import { WebView } from 'react-native-webview-messaging/WebView';
I faced this issue when i wrote :
import {ErrorMessage} from '../Components/ErrorMessage';
instead of writing like this :
import ErrorMessage from '../Components/ErrorMessage';
In my vase I was on react-native 0.46.4 and had something like import MainContainer from './app' where the app directory had a shared index.js file amongst Android and iOS, but React Native wasn't detecting an index.js inside app. Once I switched to import MainContainer from './app/index.js' it worked.
this error can be resolved by using Defualt
instead of export use export default
In my case, the problem was with incorrectly npm installation of 'AppLoading'.
I got error "Component Exception: Element type is invalid" while using react-navigation.
There was advice statement below this error to check the render method of 'App'.
I had not installed 'AppLoading' properly. I then install it as:
expo install expo-app-loading
and then changed app loading import to
import AppLoading from "expo-app-loading";
[note: make sure that your <AppLoading /> should contain onError prop].
Making these simple changes my app started working as expected.
In my case the error gets fixed by checking the versions of react-navigation and react-navigation/drawer
I was having the #react-navigation version 5
and having the #react-navigation/drawer version 6 and this was causing the issue.
I removed the version 6
and then installed the #react-navigation/drawer version 5 and the issue was fixed
I was facing the same problem I have to update all my navigation/stack and drawer to be on the latest versions all of them
I faced this issue
import Something from '#library';
Just changed to
import { Something } from '#library';
and vice verse
I handled the same problem as your error is saying that your component is invalid which is SwitchView you are returning this component as object checkitout.
hope this hint helped you i am new in stackoverflow so not familiar with answer tab
thankyou :)
How is that different from module.exports = SwitchView?
For me module.exports works for all of my js files except one.
This is probably caused by some JS module export/import issues in your program, typically for one of the two reasons listed below:
You forget to export or you export something incorrectly
You import something that doesn't exist or you import something incorrectly
I ran into similar error, but in my case it was not caused by export, but rather import. I used the import statement incorrectly to import something that doesn't exist in the module.
This error comes when you are trying to access a component which is not exported. In my case, I forgot to export a component and I was accessing it.
In my case I had replaced
const App: () => React$Node = () => {
in app.js this line with
const App = () => {
and it's worked for me.
İn My Case I implement rafce Command and Then Somehow Forgot to Export the App.js
const App = () => {
return (
<NavigationContainer theme={theme}>
<Stack.Navigator screenOptions={{ headerShown : false}} initialRouteName="Home">
<Stack.Screen name='Home' component={Home}/>
<Stack.Screen name='Details' component={Details}/>
</Stack.Navigator>
</NavigationContainer>
);
}
And then I realized that I haven't add the Export .
Then I changed My code into this and it worked Fine:
const App = () => {
return (
<NavigationContainer theme={theme}>
<Stack.Navigator screenOptions={{ headerShown : false}} initialRouteName="Home">
<Stack.Screen name='Home' component={Home}/>
<Stack.Screen name='Details' component={Details}/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

Categories

Resources