I'm trying to set up data filtering by SearchBar from react-native-elements. I'm returning some data from the server in a JSON format so it arrives in this form of an Array of Objects.
This is what I have so far:
export default function AktList() {
const [akt, setAkt] = useState([]);
const [temp, setTemp] = useState([]);
async function request() {
fetch("http://192.168.5.12:5000/aktprikaz", {
method: "get"
})
.then(res => res.json())
.then(res => setAkt(res))
.then(temp => setTemp(akt));
}
useEffect(() => {
request();
}, []);
function Item({ title, selected }) {
return (
<TouchableOpacity
onPress={() => console.log(temp)}
style={[
styles.item,
{ backgroundColor: selected ? "#6e3b6e" : "#f9c2ff" }
]}
>
<Text style={styles.title}>{title}</Text>
</TouchableOpacity>
);
}
function contains(text) {
const newData = temp.filter(item => {
const itemData = {title};
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
setAkt(newData);
}
return (
<SafeAreaView style={styles.container}>
<Header />
<SearchBar onChangeText={text => contains(text)} />
<FlatList
data={akt}
renderItem={({ item }) => <Item title={item.title} />}
keyExtractor={item => item.id}
/>
</SafeAreaView>
);
}
Currently, nor is the text updating nor is it filter anything. I've tried following this tutorial online (tho it is written using classes not functions). What am I doing wrong here?
Check below example which i created using flatlist and TextInput. Items are displayed in the form of a dropdown list when you search items. i think this will help you.
import React, { Component } from 'react';
import { View, Text, FlatList, TextInput, ListItem } from 'react-native';
class FlatListDropDown extends Component {
constructor(props) {
super(props);
this.state = {
data: [],
value: '',
};
this.arrayNew = [
{ name: 'Robert' },
{ name: 'Bryan' },
{ name: 'Vicente' },
{ name: 'Tristan' },
{ name: 'Marie' },
{ name: 'Onni' },
{ name: 'sophie' },
{ name: 'Brad' },
{ name: 'Samual' },
{ name: 'Omur' },
{ name: 'Ower' },
{ name: 'Awery' },
{ name: 'Ann' },
{ name: 'Jhone' },
{ name: 'z' },
{ name: 'bb' },
{ name: 'cc' },
{ name: 'd' },
{ name: 'e' },
{ name: 'f' },
{ name: 'g' },
{ name: 'h' },
{ name: 'i' },
{ name: 'j' },
{ name: 'k' },
{ name: 'l' },
];
}
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '100%',
backgroundColor: '#CED0CE',
}}
/>
);
};
searchItems = text => {
const newData = this.arrayNew.filter(item => {
const itemData = `${item.name.toUpperCase()}`;
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
data: newData,
value: text,
});
};
renderHeader = () => {
return (
<TextInput
style={{ height: 60, borderColor: '#000', borderWidth: 1 }}
placeholder=" Type Here...Key word"
onChangeText={text => this.searchItems(text)}
value={this.state.value}
/>
);
};
render() {
return (
<View
style={{
flex: 1,
padding: 25,
width: '98%',
alignSelf: 'center',
justifyContent: 'center',
}}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<Text style={{ padding: 10 }}>{item.name} </Text>
)}
keyExtractor={item => item.name}
ItemSeparatorComponent={this.renderSeparator}
ListHeaderComponent={this.renderHeader}
/>
</View>
);
}
}
export default FlatListDropDown;
Feel free for doubts.
Related
Goal:
Display all row in the in table at the same time.
Problem:
It display only 3 row at the same time in the table.
I would like to display all row at the same time without any limitation.
It doesn't work to use "height: '100%'"
Any idea?
Codesandbox:
https://codesandbox.io/s/mkd4dw?file=/demo.tsx
Thank you!
demo.tsx
import * as React from 'react';
import Box from '#mui/material/Box';
import Rating from '#mui/material/Rating';
import {
DataGrid,
GridRenderCellParams,
GridColDef,
useGridApiContext,
} from '#mui/x-data-grid';
function renderRating(params: GridRenderCellParams<number>) {
return <Rating readOnly value={params.value} />;
}
function RatingEditInputCell(props: GridRenderCellParams<number>) {
const { id, value, field } = props;
const apiRef = useGridApiContext();
const handleChange = (event: React.SyntheticEvent, newValue: number | null) => {
apiRef.current.setEditCellValue({ id, field, value: newValue });
};
const handleRef = (element: HTMLSpanElement) => {
if (element) {
const input = element.querySelector<HTMLInputElement>(
`input[value="${value}"]`,
);
input?.focus();
}
};
return (
<Box sx={{ display: 'flex', alignItems: 'center', pr: 2 }}>
<Rating
ref={handleRef}
name="rating"
precision={1}
value={value}
onChange={handleChange}
/>
</Box>
);
}
const renderRatingEditInputCell: GridColDef['renderCell'] = (params) => {
return <RatingEditInputCell {...params} />;
};
export default function CustomEditComponent() {
return (
<div style={{ height: 250, width: '100%' }}>
<DataGrid
rows={rows}
columns={columns}
experimentalFeatures={{ newEditingApi: true }}
/>
</div>
);
}
const columns = [
{
field: 'places',
headerName: 'Places',
width: 120,
},
{
field: 'rating',
headerName: 'Rating',
renderCell: renderRating,
renderEditCell: renderRatingEditInputCell,
editable: true,
width: 180,
type: 'number',
},
];
const rows = [
{ id: 1, places: 'Barcelona', rating: 5 },
{ id: 2, places: 'Rio de Janeiro', rating: 4 },
{ id: 3, places: 'London', rating: 3 },
{ id: 4, places: 'New York', rating: 2 },
];
You need to make use of autoHeight prop supported by the <DataGrid /> component, update your DataGrid component usage to this:
<DataGrid
autoHeight
rows={rows}
columns={columns}
experimentalFeatures={{ newEditingApi: true }}
/>
Reference: https://mui.com/x/react-data-grid/layout/#auto-height
I just started coding and I tried to delete a post through my mongoDB API. The code that I used is pretty basic, my API requests all go through a reducer which is set up pretty clear. But when I try to delete a post from my DB, I get the error ''[Unhandled promise rejection: Error: Request failed with status code 404]''. Did I do something wrong here or is this a mongoDB problem? I've included the necessary code.
This is my reducer request:
const deleteWorkout = (dispatch) => {
return async (_id) => {
await trackerApi.delete(`/workouts/${_id}`);
dispatch({ type: "delete_workout", payload: _id });
};
};
This is my complete reducer code:
import createWorkoutDataContext from "./createWorkoutDataContext";
import trackerApi from "../api/tracker";
const workoutReducer = (workouts, action) => {
switch (action.type) {
case "get_workouts":
return action.payload;
case "add_workout":
return [
...workouts,
{
title: action.payload.title,
exercises: action.payload.exercises,
},
];
case "edit_workout":
return workouts.map((Workout) => {
return Workout._id === action.payload.id ? action.payload : Workout;
});
case "delete_workout":
return workouts.filter((Workout) => Workout._id !== action.payload);
default:
return workouts;
}
};
const getWorkouts = (dispatch) => async () => {
const response = await trackerApi.get("/workouts");
dispatch({ type: "get_workouts", payload: response.data });
};
const addWorkout = (dispatch) => {
return async (title, exercises, callback) => {
await trackerApi.post("/workouts", { title, exercises });
if (callback) {
callback();
}
};
};
const editWorkout = (dispatch) => {
return async (title, exercises, _id, callback) => {
await trackerApi.put(`/workouts/${_id}`, { title, exercises });
dispatch({ type: "edit_workout", payload: { _id, title, exercises } });
if (callback) {
callback();
}
};
};
const deleteWorkout = (dispatch) => {
return async (_id) => {
await trackerApi.delete(`/workouts/${_id}`);
dispatch({ type: "delete_workout", payload: _id });
};
};
export const { Context, Provider } = createWorkoutDataContext(
workoutReducer,
{ addWorkout, getWorkouts, deleteWorkout },
[]
);
This is my code where I use the delete function:
const WorkoutListScreen = () => {
const { workouts, getWorkouts, deleteWorkout } = useContext(WorkoutContext);
return (
<View style={styles.container}>
<Text style={styles.pageTitle}>My Workouts</Text>
<NavigationEvents onWillFocus={getWorkouts} />
<FlatList
data={workouts}
keyExtractor={(item) => item._id}
renderItem={({ item }) => {
return (
<TouchableOpacity
onPress={() => navigate("WorkoutDetail", { _id: item._id })}
>
<View style={styles.row}>
<Text style={styles.title}>{item.title}</Text>
<TouchableOpacity onPress={() => deleteWorkout(item._id)}>
<Ionicons style={styles.deleteIcon} name="trash-outline" />
</TouchableOpacity>
</View>
</TouchableOpacity>
);
}}
/>
I simply included the deleteWorkout function in my TouchableOpacity, so I suppose that the problem lies within the reducer code?
here is the error I keep getting:
[Unhandled promise rejection: Error: Request failed with status code 404]
at node_modules\axios\lib\core\createError.js:16:14 in createError
at node_modules\axios\lib\core\settle.js:17:22 in settle
at node_modules\axios\lib\adapters\xhr.js:66:12 in onloadend
at node_modules\event-target-shim\dist\event-target-shim.js:818:20 in EventTarget.prototype.dispatchEvent
at node_modules\react-native\Libraries\Network\XMLHttpRequest.js:614:6 in setReadyState
at node_modules\react-native\Libraries\Network\XMLHttpRequest.js:396:6 in __didCompleteResponse
at node_modules\react-native\Libraries\vendor\emitter\_EventEmitter.js:135:10 in EventEmitter#emit
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:414:4 in __callFunction
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:113:6 in __guard$argument_0
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:365:10 in __guard
at node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:112:4 in callFunctionReturnFlushedQueue
This is what the objects in my databse look like (through Postman):
{
"userId": "615e06f36ce5e5f1a69c675e",
"title": "Defaults test",
"exercises": [
{
"exerciseTitle": "shadowboxing",
"exerciseProps": {
"time": 0,
"sets": 0,
"reps": 0
},
"_id": "6184c6fa685291fb44778df7"
},
{
"exerciseTitle": "bag workout",
"exerciseProps": {
"time": 4,
"sets": 0,
"reps": 12
},
"_id": "6184c6fa685291fb44778df8"
},
{
"exerciseTitle": "Exercise",
"exerciseProps": {
"time": 4,
"sets": 3,
"reps": 12
},
"_id": "6184c6fa685291fb44778df9"
}
],
"_id": "6184c6fa685291fb44778df6",
"__v": 0
}
I'm gratefull for your help!
I want to remove this background grey color when switching on or off in Material-Table.
Here is my table code.
Here is the code for material-table.When I inspect the code I see a button as a parent element of this Switch element. I am pretty sure this is due to that button element. I added a styling to remove the hover color and It's working fine but for this click event I am unable to change it.
here is the code for removing hover styling:
rootTable: {
"& .MuiIconButton-root": {
backgroundColor:'transparent',
},
},
<div className={classes.rootTable}>
<MaterialTable
options={{
paging: false,
addRowPosition: 'first',
search: true,
showTitle: false,
doubleHorizontalScroll: true,
minBodyHeight: '65vh',
maxBodyHeight: '68vh',
actionsColumnIndex: columns.length
}}
style={{ width: '100%' }}
actions={[
//rowData => ({
// icon: (rowData.companyAddress && rowData.companyAddress != null) ? "location_on" : "location_off",
// tooltip: "Update Address",
// onClick: (event, rowData) => dispatch(Actions.setSelectedCompanyData(rowData))
// })
rowData => ({
icon:()=>RenderSwitch(rowData),
tooltip: "Supprimer cet accès Net",
}),
]}
components={{
Toolbar: props => {
const propsCopy = { ...props };
propsCopy.showTitle = false;
return (
<Grid container direction="row" alignItems={"center"}>
<Grid container item xs={3} justify={'flex-end'}>
{t('LBL.NUMBER_OF_LOGINS')+": "+ data.length}
</Grid>
<Grid container item xs={3} justify={'flex-end'}>
{renderPasswordVisibleToggle()}
</Grid>
<Grid item xs={6}>
<MTableToolbar {...propsCopy} />
</Grid>
</Grid>
);
}
}}
isLoading={loading}
localization={{
pagination: {
labelDisplayedRows: `{from}-{to} ${t('TBL.PAGGING.TO')} {count}`,
labelRowsPerPage: t('TBL.PAGGING.LBL')
},
header: {
actions: ['Actions']
},
body: {
emptyDataSourceMessage: t('TBL.EMPTY_RECORDS_MESSAGE'),
addTooltip: t('TBL.ADD'),
editTooltip: t('TBL.EDIT'),
editRow: {
deleteText: 'Voulez-vous supprimer cette ligne?',
cancelTooltip: t('TBL.CANCEL'),
saveTooltip: t('TBL.SAVE')
}
},
toolbar: {
searchTooltip: t('TBL.SEARCH'),
searchPlaceholder: t('TBL.SEARCH')
}
}}
columns={columns.map(column => {
column.title = t(column.translate);
return column;
})}
data={data}
editable={{
onRowAdd: !loggedUser.role.includes("ROLE_SUB_USER") ? (newData) =>
new Promise((resolve, reject) => {
newData.submitted = true;
if (newData.siret.length!==14) {
setNameError({
error: true,
label: "required",
helperText: t('LBL.INVALID_COMPANY_ID') ,
validateInput: true,
});
reject();
newData.submitted = undefined;
return;
}
newData.submitted = undefined;
if (isDevelopmentEnvironment || newData?.societe?.includes('test-qa')){
dispatch(Actions.saveNewLogin(newData,resolve));
}else {
const url = apiConfig.baseUrl + '/api/company-login/check-login-status';
axios
.post(url, newData, { validateStatus: () => true })
.then(response => {
if (response?.data?.validLogin) {
setCreateData(newData);
setTimeout(() => {
resolve();
}, 600);
} else {
dispatch(MessageActions.showMessage({
message: t("LBL.ERROR_MESSAGE"),
variant: 'error'
}));
reject();
}
})
.catch(error => {
console.error(error);
reject();
});
}
}) : null,
onRowUpdate: newData => {
return new Promise(resolve => {
dispatch(Actions.updateCompanyLogin(newData,resolve));
})
}
}}
icons={{
Add: forwardRef((props, ref) => (
<Fab ref={ref} {...props} className={classes.iconButton} aria-label="add">
<AddIcon />
</Fab>
))
}}
/>
</div>
I am trying to learn react-native, I just start working on this project two days ago.
I have kind of confusing in how to get the all the image shots from dibbbler API and display it on my android emulator.
This is what I have done,
'use strict';
import React, {
AppRegistry,
Component,
Image,
ListView,
StyleSheet,
View,
} from 'react-native';
var API_URL = 'https://api.dribbble.com/v1/shots';
class myproject extends Component {
constructor(props) {
super(props);
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
}
componentDidMount() {
this.fetchData();
}
fetchData() {
fetch(API_URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.images.treaser),
loaded: true,
});
})
.done();
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.rendershots}
style={styles.listView}
/>
);
}
rendershots(shots) {
return (
<View style={styles.container}>
<Image
source={{uri: shots.images.treas}}
style={styles.images.treas}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
rightContainer: {
flex: 1,
},
treas: {
width: 53,
height: 81,
},
listView: {
paddingTop: 20,
backgroundColor: '#F5FCFF',
},
});
AppRegistry.registerComponent('myproject', () => myproject);
You need to provide credentials to retrieve the pictures from dribble.
You can register your app here to get credentials then use them to use the Dribbble API.
I am trying to follow the example (https://github.com/facebook/react-native/tree/master/Examples/UIExplorer/Navigator) on the react native site to set up my navigator, but I can't seem to get it to work. Right now I am having trouble with the ref property, as when its calls _setNavigatorRef, I am getting an error that it cannot find the property _navigator of null in the following code. It works in the example but I am not sure why:
index.ios.js
'use strict';
var React = require('react-native');
var DataEntry = require('./app/DataEntry');
var PasswordView = require('./app/PasswordView');
var GoogSignIn = require('./app/GoogSignIn');
var {
AppRegistry,
Image,
StyleSheet,
Text,
View,
Navigator,
TouchableOpacity,
} = React;
class PasswordRecovery extends React.Component {
render() {
return (
<Navigator
ref={this._setNavigatorRef}
style={styles.container}
initialRoute={{id: 'GoogSignIn', name: 'Index'}}
renderScene={this.renderScene}
configureScene={(route) => {
if (route.sceneConfig) {
return route.sceneConfig;
}
return Navigator.SceneConfigs.FloatFromRight;
}} />
);
}
renderScene(route, navigator) {
switch (route.id) {
case 'GoogSignIn':
return <GoogSignIn navigator={navigator} />;
case 'DataEntry':
return <DataEntry navigator={navigator} />;
case 'PasswordView':
return <PasswordView navigator={navigator} />;
default:
return this.noRoute(navigator);
}
noRoute(navigator) {
return (
<View style={{flex: 1, alignItems: 'stretch', justifyContent: 'center'}}>
<TouchableOpacity style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
onPress={() => navigator.pop()}>
<Text style={{color: 'red', fontWeight: 'bold'}}>ERROR: NO ROUTE DETECTED</Text>
</TouchableOpacity>
</View>
);
}
_setNavigatorRef(navigator) {
if (navigator !== this._navigator) {
this._navigator = navigator;
if (navigator) {
var callback = (event) => {
console.log(
`TabBarExample: event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from the owner.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
}
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
}
var 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('PasswordRecovery', () => PasswordRecovery);
I am just trying to get this all setup so that I can display a Google Sign in scene and then navigate from there. The code for that scene so far is here:
GoogSignIn.js
'use strict';
var React = require('react-native');
var { NativeAppEventEmitter } = require('react-native');
var GoogleSignin = require('react-native-google-signin');
var cssVar = require('cssVar');
var { Icon } = require('react-native-icons');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
TouchableHighlight,
PixelRatio,
Navigator,
} = React;
var NavigationBarRouteMapper = {
LeftButton: function(route, navigator, index, navState) {
if (index === 0) {
return null;
}
var previousRoute = navState.routeStack[index - 1];
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.navBarLeftButton}>
<Text style={[styles.navBarText, styles.navBarButtonText]}>
{previousRoute.title}
</Text>
</TouchableOpacity>
);
},
RightButton: function(route, navigator, index, navState) {
return (
null
);
},
Title: function(route, navigator, index, navState) {
return (
<Text style={[styles.navBarText, styles.navBarTitleText]}>
GOOGLE SIGN IN
</Text>
);
},
};
class GoogSignin extends React.Component {
constructor(props) {
super(props);
this.state = {
user: null
};
}
componentWillMount() {
var navigator = this.props.navigator;
var callback = (event) => {
console.log(
`NavigationBarSample : event ${event.type}`,
{
route: JSON.stringify(event.data.route),
target: event.target,
type: event.type,
}
);
};
// Observe focus change events from this component.
this._listeners = [
navigator.navigationContext.addListener('willfocus', callback),
navigator.navigationContext.addListener('didfocus', callback),
];
}
componentWillUnmount() {
this._listeners && this._listeners.forEach(listener => listener.remove());
}
componentDidMount() {
this._configureOauth(
'105558473349-7usegucirv10bruohtogd0qtuul3kkhn.apps.googleusercontent.com'
);
}
renderScene(route, navigator) {
console.log("HERE");
return (
<View style={styles.container}>
<TouchableHighlight onPress={() => {this._signIn(); }}>
<View style={{backgroundColor: '#f44336', flexDirection: 'row'}}>
<View style={{padding: 12, borderWidth: 1/2, borderColor: 'transparent', borderRightColor: 'white'}}>
<Icon
name='ion|social-googleplus'
size={24}
color='white'
style={{width: 24, height: 24}}
/>
</View>
<Text style={{color: 'white', padding: 12, marginTop: 2, fontWeight: 'bold'}}>Sign in with Google</Text>
</View>
</TouchableHighlight>
</View>
);
}
render() {
return (
<Navigator
debugOverlay={false}
style={styles.appContainer}
renderScene={this.renderScene}
navigationBar={
<Navigator.NavigationBar
routeMapper={NavigationBarRouteMapper}
style={styles.navBar}/>
}/>
);
}
_configureOauth(clientId, scopes=[]) {
console.log("WE HERE")
GoogleSignin.configure(clientId, scopes);
NativeAppEventEmitter.addListener('googleSignInError', (error) => {
console.log('ERROR signin in', error);
});
NativeAppEventEmitter.addListener('googleSignIn', (user) => {
console.log(user);
this.setState({user: user});
});
return true;
}
_signIn() {
GoogleSignin.signIn();
}
_signOut() {
GoogleSignin.signOut();
this.setState({user: null});
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
messageText: {
fontSize: 17,
fontWeight: '500',
padding: 15,
marginTop: 50,
marginLeft: 15,
},
button: {
backgroundColor: 'white',
padding: 15,
borderBottomWidth: 1 / PixelRatio.get(),
borderBottomColor: '#CDCDCD',
},
buttonText: {
fontSize: 17,
fontWeight: '500',
},
navBar: {
backgroundColor: 'white',
},
navBarText: {
fontSize: 16,
marginVertical: 10,
},
navBarTitleText: {
color: cssVar('fbui-bluegray-60'),
fontWeight: '500',
marginVertical: 9,
},
navBarLeftButton: {
paddingLeft: 10,
},
navBarRightButton: {
paddingRight: 10,
},
navBarButtonText: {
color: cssVar('fbui-accent-blue'),
},
scene: {
flex: 1,
paddingTop: 20,
backgroundColor: '#EAEAEA',
},
});
module.exports = GoogSignin;
I suspect it's a context issue. On your Navigator component, try converting from this:
ref={this._setNavigatorRef}
To this:
ref={(navigator) => this._setNavigatorRef(navigator)} (prettier IMHO)
or this:
ref={this._setNavigatorRef.bind(this)}