function exported but still shows that function isn't exported, child function in component. react

Viewed 37

I am having a problem where I want to be able to access a function that is inside a component, and use it in another function elsewhere. I had an error that says that I need to export it, after I exported it, it still shows the same error. Why is that, I triple checked and reloaded the page still the same error. Is there something I'm missing out some learning gap I may have missed a solution and a brief explanation would be nice. Thanks in advance

the error

Attempted import error: 'handleViewQuestion' is not exported from '../question/viewquestion.js'.

viewquestion.js

import React, { useState } from 'react';
import { Button } from 'semantic-ui-react';
import { currentloginid } from '../login/loginid.js';
import { deletequestion } from '../question/deletequestion.js';
import { createanswer } from '../answer/createanswer.js';
import { deleteanswer } from '../answer/deleteanswer.js';

export const ViewQuestionComponent = () => {
  let [state, setState] = useState([]);
  export const handleViewQuestion = async () => {
    try {      
      const response = await fetch('http://localhost/gotaquestion/api/api.php?action=viewquestion', {
        method: 'GET',
        credentials: 'include'
      });

      const data = await response.json();
      const result = await data;
      setState(data);
    } catch (e) {
      console.log(e);
    }
  }

  return (
    <div>
      <ViewQuestion onClick={handleViewQuestion} />
      <div id="questions">
        <input id="nq" placeholder="Create New Answer Here"></input>
        <Table rows={state}>
          <DeleteButton onClick={deletequestion} />
          <CreateNewAnswerButton onClick={createanswer} />
          <DeleteAnswerButton onClick={deleteanswer} />
        </Table>
      </div>
   </div>
  );
};

export function ViewQuestion({onClick}) {
    return (
        <Button onClick={onClick}>View Question</Button>
    );
}

export default ViewQuestion;

const Table = ({ rows, setIdTobeDeleted, children }) => (
  <table className="ui single line table">
    <tbody>
      {rows.map((row) => (
        <tr key={row.questionid}>
          <td>{row.question}</td>
          <td>{row.timestamp}</td>
          <td>{row.catagories}</td>
          <td>{row.answer === null ? "Not Answered" : row.answer}</td>
          <td>
            {React.cloneElement(children[0], { questionid: row.questionid })}
          </td>
          <td>
            {React.cloneElement(children[1], { newanswer: document.getElementById("nq").value, questionid: row.questionid })}
          </td>
          <td>
            {React.cloneElement(children[2], { questionid: row.questionid })}
          </td>
          <td>{row.questionid}</td>
        </tr>
      ))}
    </tbody>
  </table>
);

const CreateNewAnswerButton = ({ questionid, newanswer, onClick }) => (
  <button
    className="ui negative basic button"
    onClick={() => onClick(questionid, newanswer)}
  >Create New Answer</button>
);

const DeleteButton = ({ questionid, onClick }) => (
  <button
    className="ui negative basic button"
    onClick={() => onClick(questionid)}
  >Delete Question</button>
);

const DeleteAnswerButton = ({ questionid, onClick }) => (
  <button
    className="ui negative basic button"
    onClick={() => onClick(questionid)}
  >Delete Answer</button>
);

deletequestion.js

import { handleViewQuestion } from '../question/viewquestion.js';

export function deletequestion(questionid) {
    console.log(questionid);
  var deletequestionfd = new FormData();
  deletequestionfd.append('questionid', questionid);
  fetch('http://localhost/gotaquestion/api/api.php?action=deletequestion', {
      method: 'POST',
      body: deletequestionfd,
      credentials: 'include'
  })
  .then(async function(response) {
      if(response.status === 202) {
        handleViewQuestion();
      }
    })
}

3 Answers

Keep this function in a separate file

export const handleViewQuestion = async () => {
   try {      
    const response = await fetch('http://localhost/gotaquestion/api/api.php?action=viewquestion',{
        method: 'GET',
        credentials: 'include'
      });

      const data = await response.json();
      const result = await data;
      setState(data);
    } catch (e) {
      console.log(e);
    }
  }

and call from useEffect inside your ViewQuestionComponent component.

If you keep it in common function then you can use/call anywhere and here you are exporting inside an exported component.

Providing a sample, you can modify as per your requirement

 const callToApi = () => {
    return fetch('http://localhost/gotaquestion/api/api.php?action=viewquestion',{
        method: 'GET',
        credentials: 'include'
      })
      .then(res=> res.json())
      .then(res=> res)
      .catch(err=> console.log(err))
  }

then call like this wherever you need(e.g- useEffect)

   callToApi()
   .then(data => setState(data));

Imports and exports may only appear at the top level - they can't be placed in component. You have to move handleViewQuestion outside the component.

You cannot export into a function. Your code must be totally refactored.

To do it without making you use useEffect and other thing you probably don't know yet can be done with

question.js

Just store the API logic here, there is no state, no component... just reusable methods.

export const questionGet = () => {
  return fetch('http://localhost/gotaquestion/api/api.php?action=viewquestion', {
    method: 'GET',
    credentials: 'include'
  })
  .then( response => response.json() )
}

export const deleteQuestion = (questionid) => {
  var deletequestionfd = new FormData();
  deletequestionfd.append('questionid', questionid);
  return fetch('http://localhost/gotaquestion/api/api.php?action=deletequestion', {
    method: 'POST',
    body: deletequestionfd,
    credentials: 'include'
  })
  .then( response => {
    return response.status === 202);
  })
}

[...]

compo

import React, { useState } from 'react';
import { Button } from 'semantic-ui-react';
import { currentloginid } from '../login/loginid.js';
import { questionGet, questionDelete, ... } from '../question.js';


export const ViewQuestionComponent = () => {
  let [state, setState] = useState([]);

  const _show = () => {
    questionGet()
    .then( setState )
    .catch( console.error )
    ;
  };

  const _deleteQuestion = (id) => {
    questionDelete(id)
    .then( success => {
      if ( success )
        return _show();
    })
    .catch( console.error )
    ;
  }

  const _deleteAnswer = [...];
  const _createAnswer = [...];

  return (
    <div>
      <ViewQuestion onClick={_show} />
      <div id="questions">
        <input id="nq" placeholder="Create New Answer Here"></input>
        <Table rows={state}>
          <DeleteButton onClick={_deleteQuestion} />
          <CreateNewAnswerButton onClick={_createAnswer} />
          <DeleteAnswerButton onClick={_deleteAnswer} />
        </Table>
      </div>
   </div>
  );
};
Related