shio-max
@shio-max (Riooo)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

'split' of undefinedでつまずいています。

解決したいこと

react,redux,firebaseで todoアプリを作成しています。
前回のエラーに引き続き、新たなエラーでつまずいています。
こちらの記事を参考に、todoリストの編集、更新機能を実装しているのですが、 ”作業リストを保存”ボタンで発火する saveTaskList関数を更新に対応するように作り直したところ、 ボタンをクリックすると、
TypeError: Cannot read property 'split' of undefined
でエラーになります。
Firestoreの更新自体は、できているようです。

該当するソースコード

templates/CreateTaskList.jsx
const CreateTaskList = () => {
  const classes = useStyles();
  const dispatch = useDispatch();
  const selector = useSelector((state) => state);
  const uid = getUserId(selector);

  let id = window.location.pathname.split("task/create")[1];
  console.log("before /", id);
  if (id !== "") {
    id = id.split("/")[1]; // ←ココ
    console.log("after split / ", id);
  }

  const [selectedDate, setSelectedDate] = useState(new Date());
  const [items, setItems] = useState([]);
  const [note, setNote] = useState("");

  const inputNote = useCallback(
    (e) => {
      setNote(e.target.value);
    },
    [setNote]
  );

  //編集のとき
  useEffect(() => {
    if (id !== "") {
      db.collection("users")
        .doc(uid)
        .collection("tasklist")
        .doc(id)
        .get()
        .then((snapshot) => {
          const data = snapshot.data();
          setSelectedDate(data.selectedDate);
          setItems(data.items);
          setNote(data.note);
        });
    }
  }, [uid, id]);
  return (
    <section>

      省略

          <Button
            variant="contained"
            color="secondary"
            className={classes.button}
            startIcon={<AddIcon />}
            onClick={() => {
              dispatch(saveTaskList(id, selectedDate, items, note));
            }}
          >
            作業リストを保存
          </Button>

    </section>
  );
};

export default CreateTaskList;

operation.js
export const saveTaskList = (id, selectedDate, items, note) => {
  return async (dispatch, getState) => {
    const timestamp = FirebaseTimestamp.now();
    const uid = getState().users.uid;

    const data = {
      selectedDate: selectedDate,
      items: items,
      note: note,
      updated_at: timestamp,
    };

    //新規作成時 idを発行
    if (id === "") {
      const tasklistRef = db
        .collection("users")
        .doc(uid)
        .collection("tasklist")
        .doc();
      id = tasklistRef.id;
      console.log(id);
      data.id = id;
      data.created_at = timestamp;
    }

    return db
      .collection("users")
      .doc(uid)
      .collection("tasklist")
      .doc(id)
      .set(data, { merge: true })
      .then(() => {
        dispatch(push("/"));
      })
      .catch((error) => {
        alert("データの保存に失敗しました。");

        const errorMessage = error.message;
        console.log(errorMessage);
      });
  };
};

自分で試したこと

Firestoreから idをコピペして、URLの/task/create/idでページを表示させると、データの取得自体はできており、idもログで確認できます。
しかし、ボタンをクリックすると、 before / undefinedでidがundefinedになっています。
新規作成時も、ボタンクリック後、 idがundefinedになります。
とういことは、 saveTaskList関数の中身が問題なのかと思っているのですが、調べても解決策が見つからなかったので、
ぜひアドバイスして頂ければと思います。

0

1Answer

  if (id !== "") {

これだとidは絶対に空文字じゃないよね?となると思うので、「じゃundefinedはOKだな」で通ってきてるんだと思います。

単純に以下のコードと同じです。

undefined !== ""

単純にidの存在を確認したいのなら

  if (id) {
  if (Boolean(id)) {

のほうが良いのかも。

1Like

Comments

  1. @shio-max

    Questioner

    アドバイス参考になりました!
    if (id)に書き直し、このエラーは解消されましたが、もう一つのエラーが解決できてないので、全体としてはまだ行き詰まってます、、

Your answer might help someone💌