React render image from prop - image

I am trying to pass an image url to the children and then require it as follows:
import React, {Component} from 'react';
let color = require('../../css/colors.js');
let defaultStyle = {
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexBasis: 'calc(50% - 40px)',
flexDirection: 'column',
margin: '20px',
backgroundColor: color.blueCard
}
class Card extends Component {
render() {
const imgUrl = require(this.props.background);
return (<div style={{
...defaultStyle
}}>
<img src={imgUrl} alt="img"/>
</div>);
}
}
export default Card;
this.props.background looks something like this: "../../img/album1.jpg"
When im starting the React App i get the following error message on const imgUrl = require(this.props.background);:
Error: Cannot find module "."
webpackMissingModule
The React App was created using create-react-app. My guess is that webpack cant parse the resource file.

**Parent Component**
<InputSection ref="inputS" ImD={this.getData} imageUri={require(this.state.imageurl)} />
**Child Component**
<img ref="image" src={this.props.imageUri} />
try this, I think it will work.

Does not need the require in this case, You can simply get the props which you're passing from the Parent component.
for ex :
<Card background={your_value}/>
then in Card component
const imgUrl = this.props.background;

Related

How to use two useParseQuery hook in back4app parse server for implementing one to one chat app

i am trying to implement one to one chat on back4app server, i did not find any blog so going with my instinct.
i have made a class in database which has column from, to and message.
i trying to fetch from and to messages.
for that i using useParseQuery hook. How i can use this hook twice so that i can have message for both 'from' as well 'to'.
const App = () => {
const parseQuery1 = new Parse.Query('Chat_message');
parseQuery1.equalTo('from','amit');
const parseQuery2 = new Parse.Query('Chat_message');
parseQuery2.equalTo('to','amit');
const {
isLive,
isLoading,
isSyncing,
results,
count,
error,
reload
} = useParseQuery(parseQuery2);
console.log(results)
if (isLoading) {
return <ActivityIndicator />;
}
return (
<FlatList
data={results}
renderItem={({ item }) => (
<View
style={{
height: 70,
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>message: {item.get('messages')}</Text>
</View>
)}
/>
);
};
I do not know if my this approach is right, can some one enlighten or give some blog post for chat one to one. thank you good people of stack Overflow.
I used composeQuery.
i had tried with 'and' and that did not work eventually tried with or and that worked.
const parseQuery1 = new Parse.Query('Chat_message');
parseQuery1.equalTo('from','amit');
const parseQuery2 = new Parse.Query('Chat_message');
parseQuery2.equalTo('to','amit');
const composeQuery=Parse.Query.or(parseQuery2,parseQuery1)

Reconnect issue when hiding and showing React WebChat using CSS

Currently, I'm using the React version of WebChat on my site. (https://github.com/Microsoft/BotFramework-WebChat)
I'm building a feature to hide and show the WebChat element on a page. When the page first loads, the WebChat shows. When clicking on top of the WebChat (.chatbot-top-pane), the WebChat minimizes (.chat-window hides). When clicking on the div again to maximize the window (show .chat-window), the WebChat shows then tries to reconnect to the server, but fails. Why does it try to reconnect? Did the session somehow end in the background and it's trying to resume using the same token?
I tried using display: none, visibility: hidden on .chat-window.
<div className="chatbot-container">
<div className="chatbot-top-pane" onClick={handleToggleStatus.bind(this)}>
<p className="chatbot-pane-label-text">Chatbot Disco</p>
</div>
<ReactWebChat className="chat-window" directLine={createDirectLine({ token })} />
</div>
Also, I tried wrapping the .chat-window with a div and tried hiding .chat-window-container, instead:
<div className="chatbot-container">
<div className="chatbot-top-pane" onClick={handleToggleStatus.bind(this)}>
<p className="chatbot-pane-label-text">Chatbot Disco</p>
</div>
<div className="chat-window-container">
<ReactWebChat className="chat-window" directLine={createDirectLine({ token })} />
</div>
</div>
Below is a screenshot of the error message displayed on the WebChat
Error message on WebChat
I tried the same thing on the iframe version of the WebChat and had no issue at all.
When Web Chat dismounts, it triggers the DIRECT_LINE/DISCONNECT action to fire which causes DirectLine to disconnect. However, looking over your code, I'm not sure why you would have an issue with that especially since your implementation looks similar to the Minimizable WebChat Sample and you are not dismounting the Web Chat component.
I put together a simplified version of the sample that seems to work fine.
Web Chat v4
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import ReactWebChat, { createDirectLine, createStore } from 'botframework-webchat';
import classNames from 'classnames';
const WebChat = () => {
const [token, setToken] = useState('');
const [minimized, setMinimized] = useState(false);
const directLine = useMemo(() => createDirectLine({ token }), [token]);
const store = useMemo(() => createStore(), []);
const toggleChatVisivility = useCallback(() => setMinimized(minimized => !minimized), [setMinimized]);
useEffect(() => {
(async function () {
const res = await fetch('https://webchat-mockbot.azurewebsites.net/directline/token', { method: 'POST' });
const { token } = await res.json();
setToken(token);
})();
}, []);
return (
<React.Fragment>
<button onClick={toggleChatVisivility}>{minimized ? 'Show Chat' : 'Hide Chat'}</button>
<ReactWebChat className={classNames('webchat__chat-container', minimized ? 'webchat__hidden': 'webchat__visivle')} directLine={directLine} store={store} />
</React.Fragment>);
}
export default WebChat;
css
.webchat__chat-container {
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
}
.webchat__hidden {
visibility: hidden;
}
Screen capture
Hopefully the code snippets above help you figure out what's missing from your implementation. Sorry, I couldn't be more helpful. Let me know if you run into anymore questions. I'm happy to help answer them.

react hooks invalid call hooks

Hello i'm trying to load a style into my ui stuff but i'm having trouble doing that
const useStyles = makeStyles(loginPage)
const classes = useStyles();
const renderTextField = ({
label,
input,
meta: { touched, invalid, error },
...custom
}) => (
<TextField
label={label}
placeholder={label}
variant="outlined"
InputLabelProps={{
classes: {
root: classes.label,
focused: classes.focusedLabel,
error: classes.erroredLabel
}
}}
InputProps={{
classes: {
root: classes.cssOutlinedInput,
focused: classes.cssFocused,
notchedOutline: classes.notchedOutline,
},
startAdornment: (
<InputAdornment position="start">
<PersonSharpIcon style={{ fontSize: 25 , color: 'rgba(20, 176, 12,0.9)' }} />
</InputAdornment>
)
}}
error={touched && invalid}
helperText={touched && error}
{...input}
{...custom}
/>
)
error:
Error: Invalid hook call. Hooks can only be called inside of the body
of a function component.
Could someone help me how I would solve this?
It's exactly as the error message says. You need to move your hook inside the body of your function component.
React considers every function starting with 'use' as a hook. So in your case it's useStyles(). React also expects such functions to be called only from inside of the body of function components and only from the root of it (so nesting it inside loops or conditional statements is a big no - you can read about it here). Your function component is renderTextField, so as you can see you're calling useStyles() OUTSIDE of renderTextField's body.
Structuring it something like this should help:
const useStyles = makeStyles(loginPage);
const RenderTextField = ({
label,
input,
meta: { touched, invalid, error },
...custom
}) => {
const classes = useStyles(); // <-- Move it here
return (
<TextField
label={label}
...
>
...
</TextField>
);
}

Vue Native: 'Invariant Violation'

I'm trying to get up and rolling with Vue Native, and I'm running into the same error whenever I attempt to navigate beyond the initial screen
Warning: React.createElement: type is invalid -- expected a string
(for built-in components) or a class/function (for composite
components) but got: undefined. You likely forgot to export your
component from the file it's defined in, or you might have mixed up
default and named imports.
Check the render method of ReactVueComponent.
in ReactVueComponent (at SceneView.js:17)
in SceneView (at CardStack.js:466)
in RCTView (at View.js:60)
in View (at createAnimatedComponent.js:154)
in AnimatedComponent (at Card.js:12)
When searching my dir for ReactVueComponent, it doesn't exist, nor does SceneView.js, nor does RCTCView, etc. My guess is that's because they are generated with the code compiles?
My router, index.vue is set up as follows
<template>
<root>
<app-navigation></app-navigation>
</root>
</template>
<script>
import React from "react";
import { StackNavigator, navigationService } from "vue-native-router";
import { Root } from "native-base";
import WelcomeScreen from "./screen/WelcomeScreen.vue";
import HomeScreen from "./screen/home.vue";
const AppNavigation = StackNavigator(
{
Welcome: { screen: WelcomeScreen },
Home: { screen: HomeScreen }
},
{
initialRouteName: "Welcome",
headerMode: "none"
}
);
export default {
components: { Root, AppNavigation }
};
</script>
My WelcomeScreen component(this loads correctly. The button, on push, throws the error)
<template>
<nb-content padder>
<nb-form>
<view :style="{marginTop:300}">
<nb-button block :on-press="login">
<nb-text>Login</nb-text>
</nb-button>
</view>
</nb-content>
</template>
<script>
import { Dimensions, Platform, AsyncStorage } from "react-native";
import { NavigationActions } from "vue-native-router";
export default {
props: {
navigation: {
type: Object
}
},
methods: {
login() {
this.navigation.navigate("Home");
}
}
};
</script>
The HomeScreen component, which fails to render:
<template>
<nb-container :style="{flex:1, backgroundColor: '#fff'}">
<nb-header>
<nb-body>
<nb-title>title</nb-title>
</nb-body>
</nb-header>
<nb-content>
<nb-list>
<li>thing 1</li>
<li>thing 2</li>
<li>thing 3</li>
</nb-list>
</nb-content>
</nb-container>
</template>
<script>
import React from "react";
import { Dimensions } from "react-native";
const SCREEN_WIDTH = Dimensions.get("window").width;
export default {
props: {
navigation: Object
}
};
</script>
Any tips on this would be much appreciated. Not much out there on Vue Native yet, and I've tried to follow the few examples I've seen to the best of my ability. Double and triple-checked my dependencies and they all seem to be in place.
Seems like you are using <li> tags which are not supported. If you check native base docs. The correct tag to be used within nb-list is nb-list-item. http://docs.nativebase.io/Components.html#list-def-headref

How to richly style AOR Edit page

Have to create an edit Page editing a number of parameters on an instance of a'tale' resource.
However adding any element such as an MUI Card or even a div, is causing the app to freeze in various ways.
These are the approaches I have tried.
1) Adding a card component or placing my elements within a div for styling
export const EditorEditTale = (props) => {
return (
<Edit {...props} title="Tale Editor">
<SimpleForm >
<div>
<Image />
<TaleCardHeader props={ props } style={taleCardHeaderStyle.editor} />
</div>
</SimpleForm>
</Edit>
)
};
This is causing nothing to render.
Second approach, assuming that the record and basePath arent getting propagated to the children completely. Trying to use component like below.
const Input = ({record, basePath}) => {
return (
<div>
<LongTextInput source="taleText" />
</div>
)
}
This is causing the page to not render with everything in some kind of locking loop with the error - cannot read property touched of undefined.
How should I create a custom Edit page with a complex inputs and styling.
UPDATE: Been trying to write a custom form to substitute the SimpleForm component with no luck so far.
To create a custom form you can follow these steps:
make an exact copy of SimpleForm to your project.
rename SimpleForm to what you want.
fix all the relative imports.
test the new form until it works.
I made a minimum working form based on current master branch's SimpleForm
import React, { Children, Component } from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import compose from 'recompose/compose';
import getDefaultValues from 'admin-on-rest/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/mui/form/FormField';
import Toolbar from 'admin-on-rest/mui/form/Toolbar';
const formStyle = { padding: '0 1em 1em 1em' };
export class PostForm extends Component {
handleSubmitWithRedirect = (redirect = this.props.redirect) => this.props.handleSubmit(values => this.props.save(values, redirect));
render() {
const { children, invalid, record, resource, basePath, submitOnEnter, toolbar } = this.props;
return (
<form className="simple-form">
<Field name="name_of_a_field" component="input" />
{toolbar && React.cloneElement(toolbar, {
handleSubmitWithRedirect: this.handleSubmitWithRedirect,
invalid,
submitOnEnter,
})}
</form>
);
}
}
PostForm.propTypes = {
basePath: PropTypes.string,
children: PropTypes.node,
defaultValue: PropTypes.oneOfType([
PropTypes.object,
PropTypes.func,
]),
handleSubmit: PropTypes.func, // passed by redux-form
invalid: PropTypes.bool,
record: PropTypes.object,
resource: PropTypes.string,
redirect: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]),
save: PropTypes.func, // the handler defined in the parent, which triggers the REST submission
submitOnEnter: PropTypes.bool,
toolbar: PropTypes.element,
validate: PropTypes.func,
};
PostForm.defaultProps = {
submitOnEnter: true,
toolbar: <Toolbar />,
};
const enhance = compose(
connect((state, props) => ({
initialValues: getDefaultValues(state, props),
})),
reduxForm({
form: 'record-form',
enableReinitialize: true,
}),
);
export default enhance(PostForm);
The above code works for AOR's example.
I hope this helps.
(import might be slightly different when you have AOR as npm dependency :
import getDefaultValues from 'admin-on-rest/lib/mui/form/getDefaultValues';
import FormField from 'admin-on-rest/lib/mui/form/FormField';
import Toolbar from 'admin-on-rest/lib/mui/form/Toolbar';
)
Documenting my final answer. You have to create a custom Redux Form. You can use AOR Input components straight. They come prewrapped for Redux Form.
import { Field, reduxForm } from 'redux-form';
import compose from 'recompose/compose';
import { connect } from 'react-redux';
class StyledForm extends Component {
// Newer version of aor needs this function defined and passed to save buttons. All props are being passed by parent List component.
handleSubmitWithRedirect = (redirect = this.props.redirect) => this.props.handleSubmit(values => this.props.save(values, redirect));
render() {
const { handleSubmit, invalid, record, resource, basePath } = this.props
return (<div>
<form onSubmit={handleSubmit} >
<Card >
<CardText >
//This component simply displays data, something not possible very easily with SimpleForm.
<HeaderComp basePath={basePath} record={record} />
<Field source="category_id"
optionText="categoryName"
reference="categories"
resource={resource}
record={record}
basePath={basePath}
name="NAME OF THE FIELD IN YOUR REDUX DATASTORE"
component={REFERENCEFIELDCOMP} />
//create complex div structures now.
<div >
<span>Tale</span>
<Field resource={resource} record={record} basePath={basePath} name="taleText" component={TextInput} />
</div>
</CardText >
<MuiToolbar>
<ToolbarGroup>
<SaveButton handleSubmitWithRedirect={this.handleSubmitWithRedirect}/>
//Add custom buttons with custom actions
<Field record={record} name="status" component={EditButtons} />
</ToolbarGroup>
</MuiToolbar>
</Card>
</form>
</div>)
}
};
const enhance = compose(
connect((state, props) => ({
initialValues: getDefaultValues(state, props),
})),
reduxForm({
form: 'record-form',
enableReinitialize: true,
}),
);
export default enhance(StyledForm);
You will have to either import or copy getDefaultValues from AOR in the node modules.
I copied it into the file below.
import getDefaultValues from '../functions/getDefaultValues';
If you need a referenceField in your field. Then wrap it in a custom component like shown below
const DropDownSelector = ({optionText, ...props}) => {
return (
<ReferenceInput {...props} label="" >
<SelectInput optionText={optionText} />
</ReferenceInput>
)
}

Resources