Monitoring Services And Characteristics on React-Native - javascript

I have two questions for you about my code :)
I'm creating an android to connect to ble device. I'm using ble-plx library.
import React, {Component} from 'react';
import { Platform, View, Text } from 'react-native';
import { BleManager } from 'react-native-ble-plx';
export default class Main extends Component {
constructor() {
super();
this.manager = new BleManager()
this.state = {info: "", values: {}}
this.deviceprefix = "Device";
this.devicesuffix_dx = "DX";
this.sensors = {
"0000f0fd-0001-0008-0000-0805f9b34fb0" : "Acc+Gyr+Mg",
"0000f0f4-0000-1000-8000-00805f9b34fb" : "Pressure"
}
}
serviceUUID() {
return "0000f0f0-0000-1000-8000-00805f9b34fb"
}
notifyUUID(num) {
return num
}
model_dx (model) {
return this.deviceprefix + model + this.devicesuffix_dx
}
info(message) {
this.setState({info: message})
}
error(message) {
this.setState({info: "ERROR: " + message})
}
updateValue(key, value) {
this.setState({values: {...this.state.values, [key]: value}})
}
componentWillMount(){
const subscription = this.manager.onStateChange((state) => {
if (state === 'PoweredOn') {
this.scanAndConnect();
subscription.remove();
}
}, true);
}
async requestPermission() {
try {
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
this.setState({permissionStatus:'granted'});
}else if(granted === PermissionsAndroid.RESULTS.DENIED) {
this.setState({permissionStatus:'denied'});
}else{
}
} catch (err) {
console.error(err)
}
}
scanAndConnect(){
this.manager.startDeviceScan(null, null, (error, device) => {
if (error) {
return
}
let model = '0030';
if (device.name == this.model_dx(model) ) {
this.manager.stopDeviceScan();
device.connect()
.then((device) => {
this.info("Discovering services and characteristics ")
return device.discoverAllServicesAndCharacteristics()
})
.then((device) => {
this.info("SetupNotification")
return this.setupNotifications(device)
})
.catch((error) => {
this.error(error.message)
});
}
});
}
async setupNotifications(device) {
for (const id in this.sensors) {
const service = this.serviceUUID(id)
const characteristicN = this.notifyUUID(id)
device.monitorCharacteristicForService(service, characteristicN, (error, characteristic) => {
if (error) {
this.error(error.message)
return
}
this.updateValue(characteristic.uuid, characteristic.value)
})
}
}
render() {
return (
<View>
<Text>{this.state.info}</Text>
{Object.keys(this.sensors).map((key) => {
return <Text key={key}>
{this.sensors[key] + ": " + (this.state.values[this.notifyUUID(key)] || "-")}
</Text>
})}
</View>
)
}
}
I have two question for you:
1) The monitoring give me values like:
For example in the case of "Pressure" the value: "ZABIAGYAZwBoAA=="
I should receive a number not string, I have tried to convert Text into Binary and then Binary to Decimal. How can I do, in your opinion in the app?
2)
I print the values using:
<Text>{this.state.info}</Text>
{Object.keys(this.sensors).map((key) => {
return <Text key={key}>
{this.sensors[key] + ": " + (this.state.values[this.notifyUUID(key)] || "-")}
</Text>
But If I wanted to access the "pressure" value directly, how could I do it? To be clear if I wanted to, for example, passing the value that remembers me pressure on another page?
Thank you all for the support!

install this library:
npm install --save base-64
import it in your Main class:
import base64 from 'base-64'
then in your updateValue method:
updateValue(key, value) {
const readebleData = base64.decode(value);
this.setState({values: {...this.state.values, [key]: readebleData}})
}
If you want to pass the readableData to another class you should use library like react-redux or passing the variable during the transition to the new class, for example using react-native-router-flux:
Actions.pageKey({ data: readebleData })

Related

Redux+Reactjs+NodeJS How to get a specific value from the database and display it to the screen by redux?

i am new, and am getting acquainted with i reactjs and nodejs, i am writing a website in which i want to write a function to get the current login information of the user through redux, and then after then assign the obtained user value to react-select, then from react-select, we select that user to perform the assignment of new data to the database from reactjs. However, I have not been able to get the logged in user information through redux. This is my code, anyone have any ideas? Thanks very much
here is my FE(Reactjs code):
here is DoctorManageSchedule.js:
import React, { Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { connect } from 'react-redux';
import './ManageSchedule.scss';
import Select from 'react-select';
import * as actions from "../../../store/actions";
import { CRUD_ACTIONS, LANGUAGES, dateFormat } from '../../../utils';
import DatePicker from '../../../components/Input/DatePicker';
import moment from 'moment';
import { toast } from "react-toastify";
import _ from 'lodash';
import { saveBulkScheduleDoctor, getScheduleDoctorById } from '../../../services/userService';
import DetailDoctor from './DetailDoctor';
class DoctorManageSchedule extends Component {
constructor(props) {
super(props);
this.state = {
arrDoctor: [],
selectedDoctor: {},
currentDate: '',
rangeTime: [],
minDate: moment().calendar(),
}
}
async componentDidMount() {
this.props.fetchDoctor(this.props.match.params.id);
this.props.fetchAllScheduleTimes();
}
async componentDidUpdate(prevProps, prevState, snapshot) {
if (prevProps.doctor !== this.props.doctor) {
let dataSelect = this.buildDataInputSelect(this.props.doctor)
this.setState({
arrDoctor: dataSelect
})
}
if (prevProps.allScheduleTime !== this.props.allScheduleTime) {
let data = this.props.allScheduleTime;
if (data && data.length > 0) {
data = data.map(item => ({ ...item, isSelected: false }))
}
this.setState({
rangeTime: data
})
}
}
buildDataInputSelect = (inputData) => {
let result = [];
let { language } = this.props;
if (inputData && inputData.length > 0) {
inputData.map((item, index) => {
let object = {};
let labelEn = `${item.lastName} ${item.firstName}`;
let labelVi = `${item.firstName} ${item.lastName}`;
object.label = language === LANGUAGES.VI ? labelVi : labelEn;
object.value = item.id;
result.push(object)
})
}
return result;
}
handleChangeSelect = async (selectedOption) => {
this.setState({ selectedDoctor: selectedOption });
}
handleOnChangeDatePicker = (date) => {
this.setState({
currentDate: date[0]
})
}
handleClickBtnTime = (time) => {
let { rangeTime } = this.state;
if (rangeTime && rangeTime.length > 0) {
rangeTime = rangeTime.map(item => {
if (item.id === time.id) item.isSelected = !item.isSelected;
return item;
})
this.setState({
rangeTime: rangeTime
})
}
}
handleSaveSchedule = async () => {
let { rangeTime, selectedDoctor, currentDate } = this.state;
let result = [];
if (!currentDate) {
toast.error("Invalid date!");
}
if (selectedDoctor && _.isEmpty(selectedDoctor)) {
toast.error("Invalid selected doctor! ");
console.log('check doctor: ', this.state)
return;
}
let formatedDate = new Date(currentDate).getTime();
if (rangeTime && rangeTime.length > 0) {
let selectedTime = rangeTime.filter(item => item.isSelected === true);
if (selectedTime && selectedTime.length > 0) {
selectedTime.map((schedule, index) => {
let object = {};
object.doctorId = selectedDoctor.value;
object.date = formatedDate;
object.timeType = schedule.keyMap;
result.push(object);
})
} else {
toast.error("Invalid selected time! ");
return;
}
}
let res = await saveBulkScheduleDoctor({
arrSchedule: result,
doctorId: selectedDoctor.value,
formatedDate: formatedDate
})
if (res && res.errCode === 0) {
toast.success("Save Infor succeed!");
} else {
toast.error("error saveBulkScheduleDoctor ");
console.log('error saveBulkScheduleDoctor >>> res: ', res)
}
console.log('bao phuc check result: ', result);
console.log('check res: saveBulkScheduleDoctor : ', res);
}
render() {
let { rangeTime, arrDoctor } = this.state;
console.log("check doctor:", arrDoctor)
let { language } = this.props;
let today = new Date(new Date().setDate(new Date().getDate()));
return (
<div className="manage-schedule-container">
<div className="m-s-title">
<FormattedMessage id="manage-schedule.title"></FormattedMessage>
</div>
<div className="container">
<div className="row">
<div className="col-6 form-group">
<label>
<FormattedMessage id="manage-schedule.choose-doctor" /> </label>
<Select
value={this.state.selectedDoctor}
onChange={this.handleChangeSelect}
options={this.state.listDoctors}
/>
</div>
<div className="col-6 form-group">
<label>
<FormattedMessage id="manage-schedule.choose-date" /> </label>
<DatePicker
value={this.state.currentDate}
className="form-control"
onChange={this.handleOnChangeDatePicker}
minDate={today}
/>
</div>
<div className="col-12 pick-hour-container">
{rangeTime && rangeTime.length > 0 &&
rangeTime.map((item, index) => {
return (
<button className={item.isSelected === true ?
"btn btn-schedule active" : "btn btn-schedule"}
key={index} onClick={() => this.handleClickBtnTime(item)}>
{language === LANGUAGES.VI ? item.valueVi : item.valueEn}
</button>
)
})}
</div>
<div className="col-12">
<button className="btn btn-primary btn-save-schedule"
onClick={() => this.handleSaveSchedule()}>
<FormattedMessage id="manage-schedule.save" />
</button>
</div>
</div>
</div>
</div>
);
}
}
const mapStateToProps = state => {
return {
language: state.app.language,
isLoggedIn: state.user.isLoggedIn,
doctor: state.admin.doctor,
allScheduleTime: state.admin.allScheduleTime,
};
};
const mapDispatchToProps = dispatch => {
return {
fetchDoctor: () => dispatch(actions.fetchDoctorStart()),
fetchAllScheduleTimes: () => dispatch(actions.fetchAllScheduleTimes())
};
};
export default connect(mapStateToProps, mapDispatchToProps)(DoctorManageSchedule);
and here is my actionTypes.js:
const actionTypes = Object.freeze({
FETCH_DOCTOR_SUCCESS: 'FETCH_DOCTOR_SUCCESS',
FETCH_DOCTOR_FAILED: 'FETCH_DOCTOR_FAILED',
})
export default actionTypes;
and here is my adminActions.js:
export const fetchDoctorStart = id => () => {
return async (dispatch, getState) => {
try {
let res = await getScheduleDoctorById(id);
if (res && res.errCode === 0) {
dispatch({
type: actionTypes.FETCH_DOCTOR_SUCCESS,
dataDoctor: res.data
})
} else {
toast.error("Failed to fetch doctor");
dispatch(fetchDoctorFailed());
}
} catch (e) {
toast.error("Failed to fetch doctor");
dispatch(fetchDoctorFailed());
console.log("check fetch doctor failed: ", e);
}
}
};
export const fetchDoctorSuccess = (data) => ({
type: actionTypes.FETCH_DOCTOR_SUCCESS,
doctor: data
})
export const fetchDoctorFailed = () => ({
type: actionTypes.FETCH_DOCTOR_FAILED,
})
here is my adminReducer.js:
case actionTypes.FETCH_DOCTOR_SUCCESS:
state.doctor = action.dataDoctor;
return {
...state,
}
case actionTypes.FETCH_DOCTOR_FAILED:
state.doctor = [];
return {
...state,
}
here is my userService.js:
const getScheduleDoctorById = (inputId) => {
return axios.get(`/api/get-schedule-doctor-by-id?id=${inputId}`)
}
here is my BE(Nodejs code):
here is web.js:
router.get('/api/get-schedule-doctor-by-id', doctorController.getScheduleById);
here is doctorController.js:
let getScheduleById= async (req, res) => {
try {
let infor = await doctorService.getScheduleById(req.query.id);
return res.status(200).json(infor);
} catch (e) {
console.log(e);
return res.status(200).json({
errCode: -1,
errMessage: 'Error from the server'
})
}
}
here is doctorService.js:
let getScheduleById = (inputId) => {
return new Promise(async (resolve, reject) => {
try {
if (!inputId) {
resolve({
errCode: 1,
errMessage: 'Missing required parameter!'
})
} else {
let data = await db.User.findOne({
where: {
id: inputId
},
attributes: {
exclude: ['password']
},
include: [
{ model: db.Allcode, as: 'positionData', attributes: ['valueEn', 'valueVi'] },
{
model: db.Doctor_Infor,
attributes: {
exclude: ['id', 'doctorId']
}
},
],
raw: false,
nest: true
})
if (data && data.image) {
data.image = new Buffer(data.image, 'base64').toString('binary');
}
if (!data) data = {};
resolve({
errCode: 0,
data: data
})
}
} catch (e) {
reject(e);
}
})
}
when i run the app i only get the available time slots from the database, but no info about who is logged in, i checked the network tab, but it seems the api gets the user info via redux do not run. Or does anyone have a way to do it other than using redux, that the user (doctor) can set his own schedule and save it to the database? However, I don't know why, please comment, thanks a lot

Setting state in react native freezes app

In a react native I am trying create a class component that loads a list of categories with a tag and an AWS S3 image attached.
If you look at this code the app freezes on the line:
this.setState({ categories });
But if I comment out that line the console logs that categories array just fine.
Please help any ideas why?
I have tried creating a functional component also but same this happens.
import React, { Component, setState } from "react";
import { View, StyleSheet } from "react-native";
import { isTablet } from "react-native-device-detection";
import { getRecipeCategories } from "../../api/recipeCategoriesApi";
import CategoryImageItem from "./CategoryImageItem";
import { getS3Image, deleteS3Image } from "../../utility/amplify";
class CategoryImagePicker extends Component {
state = {
categories: [],
};
async componentDidMount() {
console.log("loadCats");
let res = await fetch("http://192.168.1.4:4000/api/recipe_categories");
let categories = await res.json();
for (const category of categories) {
const imgUrl = await getS3Image(category.category_image);
category.imageUrl = imgUrl.split("?")[0];
}
console.log("returned");
this.setState({ categories });
console.log("set done...", categories);
}
loadViews() {
let i = 0;
let rowType = "odd";
let viewRows = [];
const { categories } = this.state;
console.log(categories.length);
while (i < categories.length) {
console.log("//", i);
if (isTablet) {
switch (rowType) {
case "odd":
if (i == categories.length - 1) {
viewRows.push(this.renderEvenRow(i, categories[i]));
} else {
viewRows.push(
this.renderOddRow(i, categories[i], categories[i + 1])
);
rowType = "even";
i += 2;
}
break;
case "even":
viewRows.push(this.renderEvenRow(i, categories[i]));
rowType = "odd";
i += 1;
break;
default:
break;
}
} else {
viewRows.push(this.renderEvenRow(i, categories[i]));
}
}
return viewRows;
}
handleShowRecipesForCategory = (category) => {
this.props.onShowRecipesForCategory(category);
};
renderOddRow(i, categoryLeft, categoryRight) {
return (
<View style={styles.oddRow} key={i}>
<CategoryImageItem
category={categoryLeft}
onShowRecipesForCategory={() =>
this.handleShowRecipesForCategory(categoryLeft)
}
/>
<CategoryImageItem
category={categoryRight}
onShowRecipesForCategory={() =>
this.handleShowRecipesForCategory(categoryRight)
}
/>
</View>
);
}
renderEvenRow(i, category) {
return (
<View style={styles.evenRow} key={i}>
<CategoryImageItem
category={category}
onShowRecipesForCategory={() =>
this.handleShowRecipesForCategory(category)
}
/>
</View>
);
}
render() {
return <View style={styles.container}>{this.loadViews()}</View>;
}
}
componentDidMount shouldn’t be async.
componentDidMount(){
this.getCategories()
}
getCategories = async () => {
console.log("loadCats");
let res = await fetch("http://192.168.1.4:4000/api/recipe_categories");
let categories = await res.json();
for (const category of categories) {
const imgUrl = await getS3Image(category.category_image);
category.imageUrl = imgUrl.split("?")[0];
}
console.log("returned");
this.setState({ categories });
console.log("set done...", categories);
}
If this doesn’t work can you add what you are getting from console.log("set done...", categories); and what you expected

I got navigation as undefined in react navigation 5?

I have a reusable component for Sign in with Apple Button
After user success, i navigate hem to Home screen
But i notes when i log navigation it's log undefined,
and when i log this.props i just got the two actions i made in redux!
So how can i access to navigation in this component and why it's not accessed by default!
Log
props => {"isLogin": [Function isLogin], "storeToken": [Function storeToken]}
navigation => undefined
Code
import appleAuth, {
AppleAuthCredentialState,
AppleAuthError,
AppleAuthRealUserStatus,
AppleAuthRequestOperation,
AppleAuthRequestScope,
AppleButton,
} from '#invertase/react-native-apple-authentication';
import React from 'react';
import {ActivityIndicator, StyleSheet, View} from 'react-native';
import {connect} from 'react-redux';
import API from '../../api/API';
import {isLoginFunc} from '../../redux/actions/isLoginAction';
import {saveToken} from '../../redux/actions/saveTokenAction';
class AppleAuth extends React.Component {
constructor(props) {
super(props);
this.authCredentialListener = null;
this.user = null;
this.state = {
credentialStateForUser: -1,
loading: false,
};
}
componentDidMount() {
const {navigation} = this.props;
console.log('did-navigation', navigation);
console.log('did- this.props', this.props);
/**
* subscribe to credential updates.This returns a function which can be used to remove the event listener
* when the component unmounts.
*/
this.authCredentialListener = appleAuth.onCredentialRevoked(async () => {
// console.warn('Credential Revoked');
this.fetchAndUpdateCredentialState().catch(error =>
this.setState({credentialStateForUser: `Error: ${error.code}`}),
);
});
this.fetchAndUpdateCredentialState()
.then(res => this.setState({credentialStateForUser: res}))
.catch(error =>
this.setState({credentialStateForUser: `Error: ${error.code}`}),
);
}
componentWillUnmount() {
/**
* cleans up event listener
*/
this.authCredentialListener();
}
signIn = async () => {
// start a login request
try {
const appleAuthRequestResponse = await appleAuth.performRequest({
requestedOperation: AppleAuthRequestOperation.LOGIN,
requestedScopes: [
AppleAuthRequestScope.EMAIL,
AppleAuthRequestScope.FULL_NAME,
],
});
this.setState({loading: true});
const {
user: newUser,
email,
nonce,
fullName: {familyName, givenName},
identityToken,
realUserStatus /* etc */,
} = appleAuthRequestResponse;
let username = `${givenName} ${familyName}`;
this.user = newUser;
this.fetchAndUpdateCredentialState()
.then(res => {
this.setState({credentialStateForUser: res});
console.log('res:::', res);
})
.catch(error => {
console.log(`Error: ${error.code}`);
this.setState({credentialStateForUser: `Error: ${error.code}`});
});
if (identityToken) {
console.log('email', email);
console.log('username', username);
console.log('nonce', nonce);
this.sendData(email, username, nonce);
// e.g. sign in with Firebase Auth using `nonce` & `identityToken`
} else {
// no token - failed sign-in?
}
if (realUserStatus === AppleAuthRealUserStatus.LIKELY_REAL) {
console.log("I'm a real person!");
}
// console.warn(`Apple Authentication Completed, ${this.user}, ${email}`);
} catch (error) {
if (error.code === AppleAuthError.CANCELED) {
alert('User canceled Apple Sign in');
// console.warn('User canceled Apple Sign in.');
} else {
console.error(error);
}
}
};
fetchAndUpdateCredentialState = async () => {
if (this.user === null) {
this.setState({credentialStateForUser: 'N/A'});
} else {
const credentialState = await appleAuth.getCredentialStateForUser(
this.user,
);
if (credentialState === AppleAuthCredentialState.AUTHORIZED) {
this.setState({credentialStateForUser: 'AUTHORIZED'});
} else {
this.setState({credentialStateForUser: credentialState});
}
}
};
// Send data "name,image,email" to API
sendData = async (Email, Name, Id) => {
try {
let response = await API.post('/apple', {
email: Email,
name: Name,
id: Id,
});
let {
data: {
data: {
response: {token},
},
},
} = response;
console.log('token:?>:', token);
console.log('props', this.props);
console.log('navigation', this.props.navigation);
this.setState({loading: false});
this.props.storeToken(token);
this.props.isLogin(true);
// this.props.navigation.push('BottomTabNavigator');
} catch (err) {
console.log(err);
alert('Unexpected Error, try again later.');
this.setState({loading: false});
}
};
render() {
return (
<View style={styles.container}>
{this.state.loading ? (
<ActivityIndicator />
) : (
<AppleButton
style={styles.appleButton}
cornerRadius={5}
buttonStyle={AppleButton.Style.WHITE}
buttonType={AppleButton.Type.SIGN_IN}
onPress={() => this.signIn()}
/>
)}
</View>
);
}
}
const styles = StyleSheet.create({
appleButton: {
width: 200,
height: 50,
// margin: 10,
},
container: {
flex: 1,
justifyContent: 'center',
},
});
const mapDispatchToProps = dispatch => {
// to excute the actions we want to invok
return {
isLogin: isLogin => {
dispatch(isLoginFunc(isLogin));
},
storeToken: token => {
dispatch(saveToken(token));
},
};
};
export default connect(
null,
mapDispatchToProps,
)(AppleAuth);
-
singin.js
<AppleAuth /> in the render method
if you render your component as component, not as a navigation screen, it will not receive navigation prop. It was like this in all versions of react-navigation
Access the navigation prop from any component

Do I need something particular to use UI Fabric PeoplePicker with React?

I'm trying to use Microsoft control PeoplePicker from UI Fabric to get an Office-feel in my app.
I'm able to use control like Dropdown and button, but when I want to use PeoplePicker, I get error in code even if I change nothing.
To start my component code, I've copy-paste Normal People Picker from https://developer.microsoft.com/en-us/fabric#/controls/web/peoplepicker, and I get two error (for now).
Line 48:66: Parsing error: Unexpected token, expected "," and my line 48 is :return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
pointing item.text as string. I guess this error come from the use of as string in JS code. When I replace all as string to .toString(), the error disapear.
Unexpected token (26:79) and my line 26 is :const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru); pointing [] after IPersonaProps.
Since I take code from Microsoft, and it's not working on my computer, I guess I'm missing something. I was expecting to get the same result as the sample on their website.
I have office-ui-fabric-react in my Node's module.
Here's my code :
import * as React from 'react';
import { Checkbox } from 'office-ui-fabric-react/lib/Checkbox';
import { IPersonaProps } from 'office-ui-fabric-react/lib/Persona';
import { IBasePickerSuggestionsProps, NormalPeoplePicker, ValidationState } from 'office-ui-fabric-react/lib/Pickers';
import { people, mru } from '#uifabric/example-data';
const suggestionProps: IBasePickerSuggestionsProps = {
suggestionsHeaderText: 'Suggested People',
mostRecentlyUsedHeaderText: 'Suggested Contacts',
noResultsFoundText: 'No results found',
loadingText: 'Loading',
showRemoveButtons: true,
suggestionsAvailableAlertText: 'People Picker Suggestions available',
suggestionsContainerAriaLabel: 'Suggested contacts'
};
const checkboxStyles = {
root: {
marginTop: 10
}
};
export const PeoplePickerNormalExample: React.FunctionComponent = () => {
const [delayResults, setDelayResults] = React.useState(false);
const [isPickerDisabled, setIsPickerDisabled] = React.useState(false);
const [mostRecentlyUsed, setMostRecentlyUsed] = React.useState<IPersonaProps[]>(mru);
const [peopleList, setPeopleList] = React.useState<IPersonaProps[]>(people);
const picker = React.useRef(null);
const onFilterChanged = (
filterText: string,
currentPersonas: IPersonaProps[],
limitResults?: number
): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (filterText) {
let filteredPersonas: IPersonaProps[] = filterPersonasByText(filterText);
filteredPersonas = removeDuplicates(filteredPersonas, currentPersonas);
filteredPersonas = limitResults ? filteredPersonas.slice(0, limitResults) : filteredPersonas;
return filterPromise(filteredPersonas);
} else {
return [];
}
};
const filterPersonasByText = (filterText: string): IPersonaProps[] => {
return peopleList.filter(item => doesTextStartWith(item.text as string, filterText));
};
const filterPromise = (personasToReturn: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
if (delayResults) {
return convertResultsToPromise(personasToReturn);
} else {
return personasToReturn;
}
};
const returnMostRecentlyUsed = (currentPersonas: IPersonaProps[]): IPersonaProps[] | Promise<IPersonaProps[]> => {
setMostRecentlyUsed(removeDuplicates(mostRecentlyUsed, currentPersonas));
return filterPromise(mostRecentlyUsed);
};
const onRemoveSuggestion = (item: IPersonaProps): void => {
const indexPeopleList: number = peopleList.indexOf(item);
const indexMostRecentlyUsed: number = mostRecentlyUsed.indexOf(item);
if (indexPeopleList >= 0) {
const newPeople: IPersonaProps[] = peopleList.slice(0, indexPeopleList).concat(peopleList.slice(indexPeopleList + 1));
setPeopleList(newPeople);
}
if (indexMostRecentlyUsed >= 0) {
const newSuggestedPeople: IPersonaProps[] = mostRecentlyUsed
.slice(0, indexMostRecentlyUsed)
.concat(mostRecentlyUsed.slice(indexMostRecentlyUsed + 1));
setMostRecentlyUsed(newSuggestedPeople);
}
};
const onDisabledButtonClick = (): void => {
setIsPickerDisabled(!isPickerDisabled);
};
const onToggleDelayResultsChange = (): void => {
setDelayResults(!delayResults);
};
return (
<div>
<NormalPeoplePicker
onResolveSuggestions={onFilterChanged}
onEmptyInputFocus={returnMostRecentlyUsed}
getTextFromItem={getTextFromItem}
pickerSuggestionsProps={suggestionProps}
className={'ms-PeoplePicker'}
key={'normal'}
onRemoveSuggestion={onRemoveSuggestion}
onValidateInput={validateInput}
removeButtonAriaLabel={'Remove'}
inputProps={{
onBlur: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onBlur called'),
onFocus: (ev: React.FocusEvent<HTMLInputElement>) => console.log('onFocus called'),
'aria-label': 'People Picker'
}}
componentRef={picker}
onInputChange={onInputChange}
resolveDelay={300}
disabled={isPickerDisabled}
/>
<Checkbox label="Disable People Picker" checked={isPickerDisabled} onChange={onDisabledButtonClick} styles={checkboxStyles} />
<Checkbox
label="Delay Suggestion Results"
defaultChecked={delayResults}
onChange={onToggleDelayResultsChange}
styles={checkboxStyles} />
</div>
);
};
function doesTextStartWith(text: string, filterText: string): boolean {
return text.toLowerCase().indexOf(filterText.toLowerCase()) === 0;
}
function removeDuplicates(personas: IPersonaProps[], possibleDupes: IPersonaProps[]) {
return personas.filter(persona => !listContainsPersona(persona, possibleDupes));
}
function listContainsPersona(persona: IPersonaProps, personas: IPersonaProps[]) {
if (!personas || !personas.length || personas.length === 0) {
return false;
}
return personas.filter(item => item.text === persona.text).length > 0;
}
function convertResultsToPromise(results: IPersonaProps[]): Promise<IPersonaProps[]> {
return new Promise<IPersonaProps[]>((resolve, reject) => setTimeout(() => resolve(results), 2000));
}
function getTextFromItem(persona: IPersonaProps): string {
return persona.text as string;
}
function validateInput(input: string): ValidationState {
if (input.indexOf('#') !== -1) {
return ValidationState.valid;
} else if (input.length > 1) {
return ValidationState.warning;
} else {
return ValidationState.invalid;
}
}
/**
* Takes in the picker input and modifies it in whichever way
* the caller wants, i.e. parsing entries copied from Outlook (sample
* input: "Aaron Reid <aaron>").
*
* #param input The text entered into the picker.
*/
function onInputChange(input: string): string {
const outlookRegEx = /<.*>/g;
const emailAddress = outlookRegEx.exec(input);
if (emailAddress && emailAddress[0]) {
return emailAddress[0].substring(1, emailAddress[0].length - 1);
}
return input;
}
and I use it like this in my App. I've put <...> to keep code short. Everything is working in this section.
import React from 'react';
import { Fabric } from 'office-ui-fabric-react/lib/Fabric'
import PeoplePickerNormalExample from "./components/MyCustom_Picker.js"
class App extends React.Component {
render() {
return (
<Fabric className = "App" >
<PeoplePickerNormalExample / >
<...>
</Fabric>
);
}
}
export default App;
I don't think your app is in Typescript (TS). The Office UI examples you're copying are in TS. To convert the examples back into vanilla JS, remove the types (e.g. : string, : number, : IPersonaProps[]).
Check out this link: https://www.typescriptlang.org/play/. Paste the sample code in there to try to covert it to JS.

Redux props logging incorrect data

Right now I am trying to console.log this.streamCreatorUid, but I'm running into a peculiar issue. In my redux debugger, I can clearly see my data in the proper place.
Here is my redux data for the stream creator, directly from my debugger.
streams -
[0] -
{category(pin): "Oldschool Runescape"
displayName(pin): "admin"
streamId(pin): "98ebc719-c7d5-4558-b99d-2d9f8306ec64"
title(pin): "accounttest"
uid(pin): "wsFc7pIMq5dMtw9hPU86DzUTdLO2"
}
I am trying to console.log this.streamCreatorUid from my mapstatetoprops, but it is returning the current user Uid of u9TcrICehNMlAmqyDHQY77L9CXq1 instead. I'm quite confused as to why this is happening, considering this is not the data shown in my debugger.
This is for a personal project. In the past I've accessed redux props like this with no issues, now I'm not quite sure why this is happening.
import React from 'react';
import { database } from '../../../firebaseconfig.js';
import { connect } from 'react-redux';
class StreamFollow extends React.Component {
constructor(props) {
super(props);
this.uid = this.props.uid;
this.displayName = this.props.displayName;
this.streamCreatorUid = this.props.streamCreatorUid;
this.streamCreatorDisplayName = this.props.streamCreatorDisplayName;
}
componentShouldUpdate(prevProps) {
if (this.props.uid !== prevProps.uid) {
this.uid = this.props.uid
}
if (this.props.streamCreatorUid !== prevProps.streamCreatorUid) {
this.streamCreatorUid = this.props.streamCreatorUid;
}
}
//creates a follower object under the stream creators uid
createFollower = (e) => {
const followerRef = database.ref(`User_Follow_Info/${e}/Follower`)
const followerInfoObject = {
uid: this.uid,
displayName: this.displayName
}
followerRef.push(followerInfoObject);
}
//creates a following object under the users uid
//Add in checks to see if following object already exists. We can't follow someone multiple times
createFollowing = (user) => {
const followingRef = database.ref(`User_Follow_Info/${user}/Following`);
const followingInfoObject = {
uid: this.streamCreatorUid,
displayName: this.streamCreatorDisplayName
}
console.log(this.streamCreatorDisplayName)
//Check to see if follow already exists.
/*followingRef.once('value', function (snapshot) {
if (snapshot.hasChild(DATA HERE)) {
alert('exists');
}
}); */
var isSignedIn = this.isSignedIn;
followingRef.orderByChild('uid').equalTo(this.uid).once('value').then(snapshot => {
console.log(snapshot.val());
console.log(this.streamCreatorUid);
if (isSignedIn) {
console.log(snapshot.val())
return
} else {
followingRef.push(followingInfoObject);
}
})
}
onSubmit = () => {
if (this.props.isSignedIn === true) {
this.createFollowing(this.uid);
this.createFollower(this.streamCreatorUid);
} else {
//add in a sign in modal if user is not logged in
console.log('please sign in')
}
}
render() {
return (
<div>
<button onClick={this.onSubmit}>Follow</button>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
isSignedIn: state.auth.isSignedIn,
displayName: state.auth && state.auth.userInfo ? state.auth.userInfo.displayName : null,
uid: state.auth && state.auth.userInfo ? state.auth.userInfo.uid : null,
streamCreatorUid: state.streams && state.streams[0] ? state.streams[0].uid : null,
streamCreatorDisplayName: state.streams && state.streams[0] ? state.streams[0].displayName : null,
}
}
export default connect(mapStateToProps)(StreamFollow);

Categories

Resources