admin管理员组

文章数量:1435859

function Results(props) {
  var results = props.results;
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>Book Name</th>
            <th>Author</th>
            <th>S.no</th>
            <th>Series Name</th>
            <th>Type</th>
            <th>Genre</th>
            <th>Kindle/Real</th>
          </tr>
        </thead>
        <tbody>
          {results.map(result => {
            return (
              <tr key={result.name}>
                <td>{result.name}</td>
                <td>{result.author}</td>
                <td>{result.sno}</td>
                <td>{result.series}</td>
                <td>{result.type}</td>
                <td>{result.genre}</td>
                <td>{result.kindeReal}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </>
  );
}

When I try to render the above com component, I get the error:

TypeError: results.map is not a function

The results variable is an array of objects, something like:

[{"type":1},{"type":0},{"type":2}]

However, when I use the .map function, it returns the error! It is clearly an array, so why can't I use it?

This is the output of console.log(results).

[{"Book_Name":"Time Riders","Author":"Alex Scarrow","S_no":1,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Day of the Predator ","Author":"Alex Scarrow","S_no":2,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Doomsday Code","Author":"Alex Scarrow","S_no":3,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Eternal War","Author":"Alex Scarrow","S_no":4,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Gates of Rome","Author":"Alex Scarrow","S_no":5,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"City of Shadows","Author":"Alex Scarrow","S_no":6,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Pirate Kings","Author":"Alex Scarrow","S_no":7,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Mayan Prophecy","Author":"Alex Scarrow","S_no":8,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Infinity Cage","Author":"Alex Scarrow","S_no":9,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"}]

It looks like an array to me. Why is it not an array then?

This is the parent component.

import React from "react";
import Results from "./results";

function ResultsRenderer(props) {
  if (props.status === true) {
    return <Results results={props.results} />;
  } else {
    return <>{"No"}</>;
  }
}

export default ResultsRenderer;

This is the parent component of ResultsRenderer.

import React, { useState } from "react";
import { useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Form from "./searcherFormDumb";
import { toast } from "react-toastify";
import ResultsRenderer from "./resultsRenderer";

function Searcher() {
  const [answer, setAnswer] = useState(["Empty", false]);
  const [book, setBook] = useState({
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  });
  const defaultState = {
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  };

  function handleChange(event) {
    const updatedBook = { ...book, [event.target.name]: event.target.value };
    setBook(updatedBook);
  }

  function handleSubmit(event) {
    event.preventDefault();
    var changed = {};
    function populateChanged(now, old, title, temp) {
      if (now !== old) {
        temp[title] = now;
        return temp;
      } else {
        return temp;
      }
    }
    changed = populateChanged(
      book.name,
      defaultState.name,
      "Book_Name",
      changed
    );
    changed = populateChanged(
      book.author,
      defaultState.author,
      "Author",
      changed
    );
    changed = populateChanged(book.sno, defaultState.sno, "S_no", changed);
    changed = populateChanged(
      book.series,
      defaultState.series,
      "Series_Name",
      changed
    );
    changed = populateChanged(
      book.type,
      defaultState.type,
      "Fiction_Non_fiction_Companion_Prequel",
      changed
    );
    changed = populateChanged(book.genre, defaultState.genre, "Genre", changed);
    changed = populateChanged(
      book.kindleReal,
      defaultState.kindleReal,
      "Kindle_Real",
      changed
    );
    var temp_string = "";
    var key = "";
    var value = "";
    var temp_string_list = [];
    //debugger;
    for (var i = 0; i < Object.keys(changed).length; i++) {
      //debugger;
      key = Object.keys(changed)[i];
      value = changed[key];
      if (i !== Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}" AND `;
      } else if (i === Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}"`;
      }
      temp_string_list.push(temp_string);
      //debugger;
      temp_string = "";
      key = "";
      value = "";
    }

    var sql_t = temp_string_list.join("");
    var sql_tt = "SELECT * FROM books_catalouge WHERE ";
    var sql = sql_tt + sql_t;
    toast.success(sql);

    var request = new XMLHttpRequest();
    var jsql = JSON.stringify(sql);
    request.onreadystatechange = function() {
      //debugger;
      if (this.readyState == 4 && this.status == 200) {
        setAnswer([this.responseText, true]);
        console.log(`${answer}`);
      }
    };
    request.open(
      "GET",
      "http://localhost:3001/retrieve_books" + "?msg=" + jsql,
      true
    );
    request.send(jsql);
    console.log("This is the END");
    console.log(`${answer}`);
  }

  return (
    <>
      <Form book={book} onChange={handleChange} onSubmit={handleSubmit} />
      <br />
      <ResultsRenderer status={answer[1]} results={answer[0]} />
    </>
  );
}

export default Searcher;

Let me know if you need the NodeJS as well. I am using SQL to get the data, which is why I need the NodeJS. Sorry if my code is a little weird.

Thanks in advance!

function Results(props) {
  var results = props.results;
  return (
    <>
      <table>
        <thead>
          <tr>
            <th>Book Name</th>
            <th>Author</th>
            <th>S.no</th>
            <th>Series Name</th>
            <th>Type</th>
            <th>Genre</th>
            <th>Kindle/Real</th>
          </tr>
        </thead>
        <tbody>
          {results.map(result => {
            return (
              <tr key={result.name}>
                <td>{result.name}</td>
                <td>{result.author}</td>
                <td>{result.sno}</td>
                <td>{result.series}</td>
                <td>{result.type}</td>
                <td>{result.genre}</td>
                <td>{result.kindeReal}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </>
  );
}

When I try to render the above com component, I get the error:

TypeError: results.map is not a function

The results variable is an array of objects, something like:

[{"type":1},{"type":0},{"type":2}]

However, when I use the .map function, it returns the error! It is clearly an array, so why can't I use it?

This is the output of console.log(results).

[{"Book_Name":"Time Riders","Author":"Alex Scarrow","S_no":1,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Day of the Predator ","Author":"Alex Scarrow","S_no":2,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Doomsday Code","Author":"Alex Scarrow","S_no":3,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Eternal War","Author":"Alex Scarrow","S_no":4,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"Gates of Rome","Author":"Alex Scarrow","S_no":5,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"City of Shadows","Author":"Alex Scarrow","S_no":6,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Pirate Kings","Author":"Alex Scarrow","S_no":7,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Mayan Prophecy","Author":"Alex Scarrow","S_no":8,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"},{"Book_Name":"The Infinity Cage","Author":"Alex Scarrow","S_no":9,"Series_Name":"Time Riders","Fiction_Non_fiction_Companion_Prequel":"Fiction","Genre":"Sci-fi/Mystery/Thriller","Kindle_Real":"Real"}]

It looks like an array to me. Why is it not an array then?

This is the parent component.

import React from "react";
import Results from "./results";

function ResultsRenderer(props) {
  if (props.status === true) {
    return <Results results={props.results} />;
  } else {
    return <>{"No"}</>;
  }
}

export default ResultsRenderer;

This is the parent component of ResultsRenderer.

import React, { useState } from "react";
import { useEffect } from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import Form from "./searcherFormDumb";
import { toast } from "react-toastify";
import ResultsRenderer from "./resultsRenderer";

function Searcher() {
  const [answer, setAnswer] = useState(["Empty", false]);
  const [book, setBook] = useState({
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  });
  const defaultState = {
    name: "",
    author: "",
    sno: null,
    series: "",
    type: "",
    genre: "",
    kindleReal: ""
  };

  function handleChange(event) {
    const updatedBook = { ...book, [event.target.name]: event.target.value };
    setBook(updatedBook);
  }

  function handleSubmit(event) {
    event.preventDefault();
    var changed = {};
    function populateChanged(now, old, title, temp) {
      if (now !== old) {
        temp[title] = now;
        return temp;
      } else {
        return temp;
      }
    }
    changed = populateChanged(
      book.name,
      defaultState.name,
      "Book_Name",
      changed
    );
    changed = populateChanged(
      book.author,
      defaultState.author,
      "Author",
      changed
    );
    changed = populateChanged(book.sno, defaultState.sno, "S_no", changed);
    changed = populateChanged(
      book.series,
      defaultState.series,
      "Series_Name",
      changed
    );
    changed = populateChanged(
      book.type,
      defaultState.type,
      "Fiction_Non_fiction_Companion_Prequel",
      changed
    );
    changed = populateChanged(book.genre, defaultState.genre, "Genre", changed);
    changed = populateChanged(
      book.kindleReal,
      defaultState.kindleReal,
      "Kindle_Real",
      changed
    );
    var temp_string = "";
    var key = "";
    var value = "";
    var temp_string_list = [];
    //debugger;
    for (var i = 0; i < Object.keys(changed).length; i++) {
      //debugger;
      key = Object.keys(changed)[i];
      value = changed[key];
      if (i !== Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}" AND `;
      } else if (i === Object.keys(changed).length - 1) {
        temp_string = `${key} = "${value}"`;
      }
      temp_string_list.push(temp_string);
      //debugger;
      temp_string = "";
      key = "";
      value = "";
    }

    var sql_t = temp_string_list.join("");
    var sql_tt = "SELECT * FROM books_catalouge WHERE ";
    var sql = sql_tt + sql_t;
    toast.success(sql);

    var request = new XMLHttpRequest();
    var jsql = JSON.stringify(sql);
    request.onreadystatechange = function() {
      //debugger;
      if (this.readyState == 4 && this.status == 200) {
        setAnswer([this.responseText, true]);
        console.log(`${answer}`);
      }
    };
    request.open(
      "GET",
      "http://localhost:3001/retrieve_books" + "?msg=" + jsql,
      true
    );
    request.send(jsql);
    console.log("This is the END");
    console.log(`${answer}`);
  }

  return (
    <>
      <Form book={book} onChange={handleChange} onSubmit={handleSubmit} />
      <br />
      <ResultsRenderer status={answer[1]} results={answer[0]} />
    </>
  );
}

export default Searcher;

Let me know if you need the NodeJS as well. I am using SQL to get the data, which is why I need the NodeJS. Sorry if my code is a little weird.

Thanks in advance!

Share Improve this question edited Oct 11, 2019 at 15:51 Dark Programmer asked Oct 11, 2019 at 14:43 Dark ProgrammerDark Programmer 5423 gold badges7 silver badges21 bronze badges 8
  • sounds like the first time it loads there is no data.... console.log("I am ", results); and see what it is – epascarello Commented Oct 11, 2019 at 14:45
  • 2 @jdn... look at the code – epascarello Commented Oct 11, 2019 at 14:46
  • 1 Please console.log(props.results) in the first line, and add the result to the question. – SuleymanSah Commented Oct 11, 2019 at 14:47
  • 1 You're probably using <Results results={this.state.x} /> in the parent component. All you need to do to fix this is to make sure that this.state.x is always an Array, i.e. starts out as []. – user5734311 Commented Oct 11, 2019 at 14:55
  • 1 Try logging typeof results, my suspicion is that it's a string instead of an array – Ferrybig Commented Oct 11, 2019 at 16:03
 |  Show 3 more comments

6 Answers 6

Reset to default 11

Function map() can be used only on array. In this situation it looks like props.results is not array or has not been set yet (this can happen if you are fetching data with Axios or something like that).

I would recommend you to place something like this at the start of function:

if (!props.results) return 'no data';
if (!Array.isArray(props.results)) return 'results are not array'

after clarification

You get response on your onreadystatechange request which usualy comes in JSON or XML. I think your answer is stringified json. Try to use JSON.parse(response) in case of JSON or (new DOMParser()).parseFromString(response,"text/xml") in case of XML.

In your component it may look like this

request.onreadystatechange = function() {
   (this.readyState == 4 && this.status == 200)
      && setAnswer([JSON.parse(this.responseText), true]);
};

I'm seeing similar behavior when deserializing a simple .json file:

const stringifiedData = fs.readFileSync(animalsPath);
const animalData = JSON.parse(stringifiedData);
const animals = animalData.map(animal => {
    return new Animal(animal)
})

Oddly, the example I'm following is doing a string dot notation that seems to satisfy V8 that the object is an array, even though it's output in console.out does not change. The following does work but I don't know why. Any ideas?

const stringifiedData = fs.readFileSync(animalsPath);
const animalData = JSON.parse(stringifiedData).animals;
const animals = animalData.map(animal => {
    return new Animal(animal)
})  

I also got the same error while accessing data element of an array. here is what I did:

{standardObj ? (
    {standardObj.map((obj: any) => {
      return (
        <Grid item>
          <FormControlLabel
            className={styles.CheckboxLabel}
            key={obj.Code}
            control={
              <Checkbox
                onChange={handleCheckElement}
                name={obj.FullName}
                value={obj.Code}
              />
            }
            label={obj.FullName}
          />
        </Grid>
      );
    })}
) : null }

I faced the same problem and appars that for the useState Hook is very important the type of data of the inital value, I had as initial value a 0 int and cos that react didn't recognize the update as array.

I am new to React and found out that if a variable is empty / undefined and used with "map" function, the React throws that exception. My solution was to check a variable for "undefined" and length > 0.

Most of the time this problem is because of wrong syntax.

where there is

 results.map(result => {
 ........................
 }

just do

results.map(result => (
 ........................
 )

本文标签: javascriptHow to fix quotTypeError resultsmap is not a functionquotin ReactStack Overflow