Home > Software engineering >  Cannot fix "Uncaught TypeError: posts.map is not a function" error
Cannot fix "Uncaught TypeError: posts.map is not a function" error

Time:06-09

I am creating a sns-like web application. As one of the functions, I am trying to display all posts users made. However, my code shows nothing and get an error on console saying "Uncaught TypeError: posts.map is not a function". I am totally a beginner in Javascript, react and firebase. Could anyone look into my code? Thank you.

import React, { useState, useEffect } from 'react';
import "./Post.css";
import Posts from "./Posts.js";
import { getFirestore } from "firebase/firestore";
import { collection, doc, onSnapshot } from "firebase/firestore";
import { useNavigate } from "react-router-dom";
import ImageUpload from "./ImageUpload.js";

function Post( {user} ) {
    const db = getFirestore();
    const navigate = useNavigate("");
    const [posts, setPosts] = useState('');
    const colRef = collection(db, 'posts');

  useEffect(()=>
    onSnapshot(colRef,(snapshot) => {
        setPosts(
            snapshot.docs.map((doc) => {
                return{
                    post: doc.data(),
                    id: doc.id
                };
            })
        );
    }),
  []);

    return (
        <div className = "post">
            <ImageUpload username = {user?.displayName} />

            {
                posts.map(({id, post}) => (
                    <Posts key = {id} 
                    postId = {id} 
                    origuser = {user?.displayName}
                    username = {post.username}
                    userId = {user.uid}
                    caption =  {post.caption}
                    imageUrl = {post.imageUrl}
                    noLikes = {post.noLikes}
                    />
                ))
            }
        </div>
    )
}

export default Post

CodePudding user response:

The first step is to initialise posts as an array, currently you have it as a string and in the string prototype there is no .map function.

const [posts, setPosts] = useState([]);

After that you need to make sure that in the setPosts call you also pass an array. By looking at the example it seems like already it is snapshot.docs.map.

CodePudding user response:

Try this :

 {
             posts && posts.map(({id, post}) => (
                    <Posts key = {id} 
                    postId = {id} 
                    origuser = {user?.displayName}
                    username = {post.username}
                    userId = {user.uid}
                    caption =  {post.caption}
                    imageUrl = {post.imageUrl}
                    noLikes = {post.noLikes}
                    />
                ))
            }

CodePudding user response:

define your state as a array

const [posts, setPosts] = useState([]);

then add extra validation layer on the map method

{

posts && posts.length > 0 && posts.map(({id, post}) => (
    <Posts key = {id} 
    postId = {id} 
    origuser = {user?.displayName}
    username = {post.username}
    userId = {user.uid}
    caption =  {post.caption}
    imageUrl = {post.imageUrl}
    noLikes = {post.noLikes}
    />
))       

}

  • Related