question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Value do not get selected in async component

See original GitHub issue

Please have a look at this code, When I click on the drop down it shows 10 values, If I select any value from these values it get selected.

But when i search in drop down for example if I type test. It then shows 10 values matching the given string ( test ). But if i try to select any value from the new data set ( which matched the ‘test’ input ) value do not get selected.

getOptions = (input: string, callback: Function) => {
        this.props.action(
            input,
            /* callback */
            (res: Object): void => {
                if ( res && res.data ) {
                    callback(null, { options: res.data });
                } else {
                    callback([]);
                }
            }
        );
    };

render() {
        const { name, label, value, multi, placeholder, onChange } = this.props;

        return (<Async
            name={name}
            label={label}
            value={value}
            placeholder={placeholder}
            autoload
            loadOptions={this.getOptions}
            onChange={onChange}
            async
            multi={multi}
        />);
    }

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:5
  • Comments:11 (1 by maintainers)

github_iconTop GitHub Comments

46reactions
shorif2000commented, Mar 14, 2018

I am passing { value: '...', label: '...' } but it does not seem to display the selected value in the box. here is my component. when i select an item my state variable holds {value: "3", label: "ACG_242-0_non_working_flows_to_test_-Template-v6.3.xls"} which gets passed onto the Async component but it does not display the value even though it is in the list

import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import FontAwesome from 'react-fontawesome';
import { isServiceName, isServiceRef } from '../../scripts/validation';
import {
    fetchExemptionType,
    fetchMarkets,
    fetchServiceDomains,
    fetchServicesList,
    fetchExemptionsForCommsmatrix,
    fetchSecurityEngineerList,
    fetchBusinessPriorityList
} from '../../actions/security';
import { fetchCommsmatricesByService } from '../../actions/commsmatrices';
import axios from 'axios';
import { Field, reduxForm } from 'redux-form';
import PropTypes from 'prop-types';
import { Select, Async } from "react-select";
import 'react-select/dist/react-select.css';
import { Checkbox } from 'react-bootstrap';
import {
    BootstrapTable,
    TableHeaderColumn
} from 'react-bootstrap-table';
import 'react-bootstrap-table/dist/react-bootstrap-table-all.min.css';

const ASYNC_DELAY = 500;

class SecurityExemptionsNew extends Component {
    constructor(props) {
        super(props);
        this.handleSaveBtnClick = this.handleSaveBtnClick.bind(this);
        this.handleShowError = this.handleShowError.bind(this);
        this.initData = this.initData.bind(this);
        this.renderSelectField = this.renderSelectField.bind(this);
        this.renderTextField = this.renderTextField.bind(this);
        this.updateCommsMatrix = this.updateCommsMatrix.bind(this);
        this.renderSelect2Field = this.renderSelect2Field.bind(this);
        this.clearValue = this.clearValue.bind(this);
        this.updateValue = this.updateValue.bind(this);
        this.getCommsmatrices = this.getCommsmatrices.bind(this);
        this.fnToggleCheckboxes = this.fnToggleCheckboxes.bind(this);
        this.handleCheckedValues = this.handleCheckedValues.bind(this);
        this.meta = {
            title: 'Request Exemption',
            description: 'This section allows you to request an exemption'
        };
        this.passMetaBack = this.passMetaBack.bind(this);
        this.runOnce = false;
        this.state = {
            loaded: false,
            isLoading: true,
            //country: 'AU',
			//disabled: false,
			searchable: true,
			selectValue: { value: '0', label: 'All'},
			clearable: true,
			rtl: false,
			options: [
	    	    { value: '0', label: 'All'}
	        	],
	        toggleChecked: true,
	        
        };
        this.exemptionType = {};
        this.markets = {};
        this.serviceDomain = {};
        this.servicesList = {};
        this.matrices = {};
        this.securityEngineerList = {};
        this.businessPriority = {}
        this.tableOptions = {
                paginationShowsTotal: false,
                sizePerPageList: [ {
                    text: '10', value: 10
                  }, {
                    text: '50', value: 50
                  }, {
                      text: '100', value: 100
                    } 
                  ],
            };
        this.checkedValues = [];
    }

    passMetaBack = () => {
        this.props.passMetaBack(this.meta);
    };

    handleShowError(errorMsg) {
        this.props.handleShowError({ show: true, errorMsg: errorMsg });
    }

    handleSaveBtnClick = () => {
        const { columns, onSave } = this.props;
        let params = new URLSearchParams();
        columns.forEach((column, i) => {
            if (column.field == 'source') {
                params.append(column.field, 'CCP');
            } else if (column.field == 'owner') {
                params.append(column.field, this.props.username);
            } else if (column.field !== undefined) {
                params.append(column.field, this.refs[column.field].value);
            }
        }, this);
        // You should call onSave function and give the new row
        //onSave(newRow);
        //api call

        if (!isServiceName(params.get('name'))) {
            //alert
            console.log('Invalid name');
            return;
        }

        if (!isServiceRef(params.get('ref'))) {
            //alert
            console.log('Invalid ref');
            return;
        }

        params.append('quiet', 1);
        let self = this;
        this.props.addServices(params).then(function(response) {
            let data = response.payload.data;
            if (data.header.error) {
                //@todo show error on input form
                self.handleShowError(data.header.message);
            } else {
                let newRow = {};
                newRow = data.body.recordset.record;
                onSave(newRow);
                self.sendDataBack(newRow);
            }
        });
    };

    initData() {
        let self = this;
        let promises = [];
        promises.push(this.props.fetchExemptionType());
        promises.push(this.props.fetchMarkets());
        promises.push(this.props.fetchServiceDomains());
        promises.push(this.props.fetchServicesList());
        promises.push(this.props.fetchSecurityEngineerList());
        promises.push(this.props.fetchBusinessPriorityList());
        axios.all(promises).then(function(response) {

            let data = response[0].payload.data;
            self.exemptionType = data.body.recordset.record;
            data = response[1].payload.data.body.recordset.record;
            self.markets = Object.keys(data).map(key => 
            	 data[key]
	        );
            data = response[2].payload.data;
            self.serviceDomain = data.body.recordset.record;
            data = response[3].payload.data;
            self.servicesList = data.body.recordset.record;
            data = response[4].payload.data;
            self.securityEngineerList = data.body.recordset.record;
            data = response[5].payload.data;
            self.businessPriority = data.body.recordset.record;
            self.setState({ loaded: true });
        });
    }
    
    updateCommsMatrix(service_id){

    	if(service_id > 0){
    		let self = this;
        	this.props.fetchCommsmatricesByService(service_id)
        	.then( response => {
        		let data = response.payload.data.body.recordset.record;
        		let options = self.populateOptionsObject(data, 'id', 'filename');        		
        		options.unshift({ value: '0', label: 'All'});
        		return options;
        	})
        	.then( options => this.setState({options:options,isLoading: false}));
    	}else{
    		this.setState({options:{ value: '0', label: 'All'},isLoading: false});
    	}
    }
    
    populateOptionsObject(options, key, value) {
    	return options.map((option, index) => (
    			{value : option[key], label: option[value] }
    	));
    }

    populateOptions(options, key, value) {
        return options.map((option, index) => (
            <option key={option.id} value={option[key]}>
                {option[value]}
            </option>
        ));
    }

    renderSelectField(field) {

        let options = [];
        if (field.label == 'Type') {
            options = this.populateOptions(this.exemptionType, 'name', 'name');
        } else if (field.label == 'Market') {
            options = this.populateOptions(this.markets, 'name', 'name');
        } else if (field.label == 'Service Domain') {
            options = this.populateOptions(this.serviceDomain, 'name', 'name');
        } else if (field.label == 'Service/Project/Programme') {
            options = this.populateOptions(this.servicesList, 'id', 'name');
            options.unshift(
                <option key="0" value="0" selected>
                    All
                </option>
            );
        } else if (field.label == 'Comms Matrix') {
            options.unshift(
                <option key="0" value="0" selected>
                    All
                </option>
            );
        } else if (field.label == 'Security Engineer') {
            options = this.populateOptions(this.securityEngineerList, 'email', 'email');
            options.unshift(
                <option key="0" value="" selected>
                    --Select Engineer--
                </option>
            );
        } else if (field.label == 'Business Priority') {
            options = this.populateOptions(this.businessPriority, 'name', 'name');
        }
        let id = "select_" + field.input.name;
        return (
            <div className="form-group">
                <label className="control-label col-sm-2">{field.label}</label>
                <div className="col-sm-10">
                    <select
                    	id={id}
                    	{...field.select}
                        name={field.input.name}
                        className="form-control form-control-inline"
                        type="select"
                    	onChange={event => {
                    	      //props.input.onChange(event); // <-- Propagate the event
                    	      this.updateCommsMatrix(event.target.value);
                    	    }}
                    >
                        {options}
                    </select>
                </div>
            </div>
        );
    }
    
    clearValue (e) {
		this.select.setInputValue('');
	}
    
    updateValue (newValue) {
    	if(newValue !== null){
	    	this.props.fetchExemptionsForCommsmatrix(newValue.value)
	    	.then( response => {
	    		if(this.state.toggleChecked){
		    		this.checkedValues = response.payload.data.body.recordset.record.map((option, index) => (
	            			{id : option['id'] }
	            	));
	    		}
	    		this.setState({selectValue: newValue, policies : response.payload.data.body.recordset.record});
	    	});
    	}else{
    		this.setState({selectValue: {value:"0",label:"All"}});
    	}
		
	}
    
    getCommsmatrices (input, callback) {
		input = input.toLowerCase();
		let options = this.state.options.filter(i => {
			return i.label.toLowerCase().includes(input) == true;
			//return i.label.toLowerCase().substr(0, input.length) === input;
		});

		let data = {
			options: options,//.slice(0, MAX_CONTRIBUTORS),
			complete: true //options.length <= MAX_CONTRIBUTORS,
		};

		setTimeout(function() {
			callback(null, data);
		}, ASYNC_DELAY);
	}
    
    gotoCommsmatrix (value, event) {
    	if(value.value > 0){
    		window.open(window.top.protocol + '://' + window.top.hostname + '/api/user/commsmatrix/id/'+value.value+'/format/xml');
    	}
	}
    /*
	<Select
		id={id}
		//className="col-sm-6"
		ref={(ref) => { this.select = ref; }}
		onBlurResetsInput={false}
		onSelectResetsInput={false}
		autoFocus
		options={options}
		simpleValue
		clearable={this.state.clearable}
		name={field.input.name}
		//disabled={this.state.disabled}
		value={this.state.selectValue}
		onChange={this.updateValue}
		rtl={this.state.rtl}
		searchable={this.state.searchable}
	/>
	 */
    renderSelect2Field(field){
    	let id = "select_" + field.input.name;
    	return(
    			<div className="form-group">
                	<label className="control-label col-sm-2">{field.label}</label>
                	<div className="col-sm-4">

                		<Async 
                			name={field.input.name}
                			multi={false} 
                			value={this.state.selectValue} 
                			onChange={this.updateValue} 
                			valueKey="value" 
                			labelKey="label" 
                			loadOptions={this.getCommsmatrices} 
                			onValueClick={this.gotoCommsmatrix}
                			cache={false}
                			isLoading={this.state.isLoading}
                			optionRenderer={(option) => {return option.label;}}
                		/>
					</div>
			    </div>
    	);
    }

    renderTextField(field) {
    	let value = '';
    	if (field.label == 'Requestor') {
    		value = this.props.activeUser.email;
    	}
        return (
            <div className="form-group">
                <label className="control-label col-sm-2">{field.label}</label>
                <div className="col-sm-10">
                    <input
                        name={field.input.name}
                        className="form-control form-control-inline"
                        type="text"
                        {...field.text}
                    	value={value}
                    />
                </div>
            </div>
        );
    }

    renderTextareaField(field) {
        return (
            <div className="form-group">
                <label className="control-label col-sm-2">{field.label}</label>
                <div className="col-sm-10">
                    <textarea
                        name={field.input.name}
                        className="form-control form-control-inline"
                        type="textarea"
                        {...field.text}
                    />
                </div>
            </div>
        );
    }
    
    handleCheckedValues({target}){
    	if (target.checked){    	
    		target.setAttribute('checked', true);
    		this.checkedValues.push({id:$(target).val()});
    	}else{
    		target.removeAttribute('checked');
    		let arr = this.checkedValues.filter(function(item) { 
    		    return item.id !== $(target).val()
    		})
    		this.checkedValues = arr;
    	}
    }
    
    actionButtons(cell, row, enumObject, rowIndex) {
    	let checked = true;
    	let arr = this.checkedValues.filter(function(item) { 
		    return item.id == row.id
		});
    	if(arr.length == 0){
    		checked = false;
    	}
    	return (
			<input type="checkbox" defaultChecked={checked} name="comms_matrix_flow[]" value={row.id} onClick={this.handleCheckedValues} />
    	);			
    }
    
    fnToggleCheckboxes({target})  {
        this.setState({toggleChecked : !this.state.toggleChecked})
        let elements = document.getElementsByName("comms_matrix_flow[]");
        let length = elements.length;
        if(!this.state.toggleChecked){
        	this.checkedValues = this.state.policies.map((option, index) => (
        			{id : option['id'] }
        	));
        	for(let i = 0;i<length;i++){
        		elements[i].checked = true;
        	}
        }else{
        	this.checkedValues = [];
        	
        	for(let i = 0;i<length;i++){
        		elements[i].checked = false;
        	}
        }
    }
    
    renderPolicies(){
    	if(this.state.selectValue !== null && parseInt(this.state.selectValue.value) > 0){
	    	return (
	    		<div className="form-group">
	                <label className="control-label col-sm-2">Select Denied Flow(s): 
	                	<br/> <input name="toggle_comms_matrix_flow" type="checkbox" onClick={this.fnToggleCheckboxes} defaultChecked={true} />
					Toggle All 
						<br/> <font style={{color: "#ff0000", fontSize: "11px"}}>
					Only select and group flows relevant to the exemption request to
					prevent it being declined. </font></label>
	                <div className="col-sm-10">
			            <BootstrapTable
			                keyField="id"
			                data={this.state.policies}
			                options={this.tableOptions}
			                pagination
			                striped
			                hover
			                tableHeaderClass="table-vf thead"
			             >
			            	<TableHeaderColumn dataFormat={this.actionButtons.bind(this)} width={`30px`}></TableHeaderColumn>
			                <TableHeaderColumn dataField="src">Source</TableHeaderColumn>
			                <TableHeaderColumn dataField="dst">Destination</TableHeaderColumn>
			                <TableHeaderColumn dataField="protocol" >Protocol</TableHeaderColumn>
			                <TableHeaderColumn dataField="ports">Ports</TableHeaderColumn>
			                <TableHeaderColumn dataField="type" width={`60px`}>Type</TableHeaderColumn>
			            </BootstrapTable>
			         </div>
			     </div>
		            
	        );
    	}
    	return (<div className="form-group"></div>);
    }

    render() {
    	console.log(this);
        if (!this.runOnce && this.props.isReady) {
            this.runOnce = true;
            this.initData();
        }
        const { handleSubmit } = this.props;
        let form = 'Loading...';
        if (this.state.loaded) {
        	let policiesTable = this.renderPolicies();
            return (
                <div className="container-fluid">
                    <form onSubmit={handleSubmit} className="form-horizontal">
                        <Field
                            label="Type"
                            loadFrom="exemptionType"
                            name="exemption_type"
                            component={this.renderSelectField}
                        />
                        <Field
                            label="Market"
                            loadFrom="markets"
                            name="market"
                            component={this.renderSelectField}
                        />
                        <Field
                            label="Service Domain"
                            loadFrom="serviceDomain"
                            name="service_domain"
                            component={this.renderSelectField}
                            type="select"
                        />
                        <Field
                            label="Service/Project/Programme"
                            loadFrom="servicesList"
                            name="service_id"
                            component={this.renderSelectField}
                            type="select"
                        />

                        <Field
                            label="Demand Ref"
                            name="demand_ref"
                            component={this.renderTextField}
                            type="text"
                        />
                        <Field
                            label="Exemption Summary"
                            name="name"
                            component={this.renderTextField}
                            type="text"
                        />
                        <Field
                            label="Exemption Description"
                            name="description"
                            component={this.renderTextareaField}
                            type="textarea"
                        />
                        <Field
                            label="Comms Matrix"
                            loadFrom="matrices"
                            name="comms_matrix_id"
                            component={this.renderSelect2Field}
                            type="select"
                        />
                        {policiesTable}
                        <Field
	                        label="Requestor"
	                        name="requestor"
	                        component={this.renderTextField}
	                        type="text"
	                        readonly="readonly"
	                    />
                        <Field
                            label="Security Engineer"
                            loadFrom="securityEngineerList"
                            name="security_engineer"
                            component={this.renderSelectField}
                            type="select"
                        />
                        <Field
	                        label="Link to Design Doc"
	                        name="designdoc"
	                        component={this.renderTextField}
	                        type="text"
	                    />
                        <Field
                            label="Business Priority"
                            loadFrom="businessPriority"
                            name="business_priority"
                            component={this.renderSelectField}
                            type="select"
                        />
                        <Field
	                        label="Expiry date (dd-MMM-yy)"
	                        name="expiry_date"
	                        component={this.renderTextField}
	                        type="text"
	                    />
	                    <div className="form-group">
	                		<div className="col-sm-offset-2 col-sm-10">
	                			<button id="btnSubmit" type="button" name="btnSubmit" className="btn btn-vodafone hidden-print">Submit</button>
	                		</div>
	                	</div>
                    </form>
                </div>
            );
        }

        return <div className="container-fluid">{form}</div>;
    }
}

function mapStateToProps(state) {
    return {
        securityExemptions: state.securityExemptions,
        commsmatrices: state.commsmatrices
    };
}

//Anything returned from this function will end up as props
//on the User container
function mapDispatchToProps(dispatch) {
    // Whenever getUser is called, the result should be passed
    // to all our reducers
    //return {
    //actions: bindActionCreators(Object.assign({}, fetchServices, checkServiceEditable ), dispatch)
    //};
    return bindActionCreators(
        {
            fetchExemptionType,
            fetchMarkets,
            fetchServiceDomains,
            fetchServicesList,
            fetchCommsmatricesByService,
            fetchExemptionsForCommsmatrix,
            fetchSecurityEngineerList,
            fetchBusinessPriorityList
        },
        dispatch
    );
}

SecurityExemptionsNew = connect(mapStateToProps, mapDispatchToProps)(
    SecurityExemptionsNew
);

//Decorate the form component
export default reduxForm({
    form: 'SecurityExemptionsNewForm', // a unique name for this form
    initialValues: { service_domain: 'Corporate (Internal/External)' }
})(SecurityExemptionsNew);

7reactions
gen1321commented, Dec 20, 2017

@saadbinsaeed Doc just dont get updated yet. i will do this tommorow. u need to pass {value: ‘’, label: ‘’} instead of string

Read more comments on GitHub >

github_iconTop Results From Across the Web

Selected value is not displayed in async mode - Stack Overflow
I was hoping for a fix since I have the same problem on another component and having the value disappear after the user...
Read more >
How to use the react-select.Async function in react-select | Snyk
To help you get started, we've selected a few react-select.Async examples, based on popular ways it is used in public projects.
Read more >
Async Data Fetching with React-Select - OpenReplay Blog
When this button is clicked, the fetch request runs, and another set of names will be added to the options list. import {...
Read more >
Advanced - React Select
A flexible and beautiful Select Input control for ReactJS with multiselect, autocomplete and ajax support.
Read more >
react-select: An introduction - LogRocket Blog
How do you get the value out of react-select? I've set up a working react-select async component that pulls data from an external...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found