Martin
Martin

Reputation: 445

React - property is missing in type {}

I have problem with defining what should I pass to property, which is basically function which send request to my api to get data. When I want to render Header in my Layout component, it throws an error requestAvailableContexts is missing in type {}

Is it somehow possible to make requestAvailableContexts property which represents function optional?

I can bypass error by using this <Header requestAvailableContexts={null} /> setting property to null, but I dont think this is a good approach

This is my layout component

export class Layout extends React.Component<{}, {}> {
public render() {
    return <div className="app_layout">
        // here it throws me an error that requestAvailableContexts property is missing
        <Header /> 
        //I can bypass that by setting property to null
        //<Header requestAvailableContexts={null} /> 
        <div className="app_menu col-sm-4 col-md-4 col-lg-2 no-side-padding">
            <NavMenu />
        </div>
        <div className='col-lg-10'>
            {this.props.children}
        </div>
    </div>;
}}

Header component which contains dropdown component where I need to load some data from my api and its connected to store via redux connect()

type ProcessListProps =
    HeaderState.IImporterSelectorContextState
    & typeof HeaderState.actionCreators;

class Header extends React.PureComponent<ProcessListProps, {}> {
    constructor(props) {
        super(props);
    }

    componentWillMount(): void {
        this.props.requestAvailableContexts(this.props.dataQuery);
    }

    render() {
        return (
            <header>
                <div className="app_header">
                    <div className="containerLogo">
                        <Logo />
                    </div>      
                    <nav className="">                      
                        <DropDownList
                            data={this.props.data}
                            textField={'code'}
                            value={'id'}
                            className="dd-header" />
                        <Notification />
                        <Logout />
                        <Fullscreen />
                    </nav>
                </div>
            </header>
        );
    }
}

export default connect(
    (state: ApplicationState) => state.headerContextSelector,
    HeaderState.actionCreators
)(Header) as typeof Header;

This is my component where I define reducer and action creators for Header component

const GET_AVAILABLE_CONTEXTS = "GET_AVAILABLE_CONTEXTS";
const GET_AVAILABLE_CONTEXTS_SUCCESS = "GET_AVAILABLE_CONTEXTS_SUCCESS";

export interface IImporterSelectorContextState {
    dataQuery?: ServiceApi.IDataQuery;
    data?: any[];
}

//request to api for all available contexts to user
interface AllAvailableContexts {
    type: typeof GET_AVAILABLE_CONTEXTS;
    data: { query: any }
}

export const getAvailableContexts = (dataQuery: ServiceApi.IDataQuery): AllAvailableContexts => ({
    type: GET_AVAILABLE_CONTEXTS,
    data: { query: dataQuery }
});

//successfull respond from api to get all available contexts
interface GetAllImporterContextDataSuccess {
    type: typeof GET_AVAILABLE_CONTEXTS_SUCCESS;
    data: any;
}

export const getAllImporterContextDataSuccess = (data: any): GetAllImporterContextDataSuccess => ({
    type: GET_AVAILABLE_CONTEXTS_SUCCESS,
    data: data
});

type KnownAction = 
    AllAvailableContexts |
    GetAllImporterContextDataSuccess | 
    GetAllImporterContextDataFailure

export const actionCreators = {
    requestAvailableContexts: (dataQuery: ServiceApi.IDataQuery): AppThunkAction<KnownAction> => (dispatch, getState) => {
        client.apiImporterDataPost(ServiceApi.DataQuery.fromJS(dataQuery))
            .then(result => dispatch(getAllImporterContextDataSuccess(result.data)))

        dispatch(getAvailableContexts(dataQuery));
    }
}

const unloadedState: IImporterSelectorContextState = {
    dataQuery: {
        collectionName: "",
        filter: {},
        sort: {},
        projection: {},
        take: 200,
        skip: 0,
        includeTotalCount: false,
        context: null,
        dialect: 0,
        parameters: null,
    },
    data: []
};

export const reducer: Reducer<IImporterSelectorContextState> = (state: IImporterSelectorContextState,
    incomingAction: Action) => {

    const action = incomingAction as KnownAction;
    switch (action.type) {
        case GET_AVAILABLE_CONTEXTS:
            return {
                ...state
            }
        case GET_AVAILABLE_CONTEXTS_SUCCESS:
            return {
                ...state,
                data: action.data
            }
        default:
            const exhaustiveCheck: never = action;
    }
    return state || unloadedState;
}

Upvotes: 1

Views: 1924

Answers (1)

agenthunt
agenthunt

Reputation: 8678

You are using flow types

type ProcessListProps =
    HeaderState.IImporterSelectorContextState
    & typeof HeaderState.actionCreators 
    & typeof (string) => void;

The solution is to make a check in Header component before calling that function

componentWillMount(): void {
    if(this.props.requestAvailableContexts) {
      this.props.requestAvailableContexts(this.props.dataQuery);
    }
}

Upvotes: 1

Related Questions