Trying to show only year from a date stored in mongodb database. How to do that?

48 Views Asked by At

I'm creating a website. Inside my server there's a mongoose model which saves different data in mongo database as like the date of birth. The date stored in ISODate format. But I want to use only the year or month in a react component inside the client side. How can i do that? Is there any way to format a date in react component which is called from mongodb?

import mongoose from 'mongoose';

const listingSchema = new mongoose.Schema(
    {
        givenname: {
            type: String,
            required: true,
        },
        familyname: {
            type: String,
            required: true,
        },
        dateofbirth: {
            type: Date,
            required: true,
        },
        dateofpassing: {
            type: Date,
            required: true,
        },
        imageUrl: {
            type: String,
            default: "https://cdn.pixabay.com/photo/2015/10/05/22/37/blank-profile-picture-973460_1280.png"
        },
        userRef: {
            type: String,
            required: true,
          },

    }, {timestamps: true}
)

const Listing = mongoose.model('Listing', listingSchema);

export default Listing;
import { useSelector } from 'react-redux';
import { useRef, useState, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { Link } from 'react-router-dom';

export default function () {
  const { currentUser, loading, error } = useSelector((state) => state.user);
  const [showListingsError, setShowListingsError] = useState(false);
  const [userListings, setUserListings] = useState([]);
  const dispatch = useDispatch();

    const handleShowListings = async () => {
        try {
          setShowListingsError(false);
          const res = await fetch(`/api/user/listings/${currentUser._id}`);
          const data = await res.json();
          if (data.success === false) {
            setShowListingsError(true);
            return;
          }
    
          setUserListings(data);
        } catch (error) {
          setShowListingsError(true);
        }
      };
    
  return (
    <div>
        <button onClick={handleShowListings}>Show Memorials</button>
        {userListings && userListings.length > 0 && userListings.map((listing)=> 
        <div key={listing._id}>
            <Link>
            <div>
                <img src={listing.imageUrl} alt="Person image" />
                <div>
                    <h1>{listing.givenname + ' ' + listing.familyname}</h1>
                    <p>{listing.dateofbirth.year + '-' + listing.dateofpassing.year}</p>
                </div>
            </div>
            </Link>
        </div>)}
    </div>
  )
}

1

There are 1 best solutions below

0
jQueeny On

You can update your schema to include virtuals.

This will add computed properties to your document that you can use on your React front-end. These will not show up in mongodb so you cannot query them and are only output using mongoose.

Note I have include the toJSON: { virtuals: true } option for you because otherwise when you convert the document to JSON to send over the wire, by default virtuals are not part of the JSON object.

const listingSchema = new mongoose.Schema(
   {
      //...
      dateofbirth: {
         type: Date,
         required: true,
      },
      //...
      //..
   }, 
   {
      timestamps: true,
      toJSON: {
         virtuals: true
      },
      virtuals: {
         yearOfBirth: {
            get() {
               const nd = new Date(this.dateofbirth);
               return nd.getFullYear();
            },
         },
         monthOfBirthDigit: {
            get() {
               const nd = new Date(this.dateofbirth);
               return nd.getMonth()+1; // +1 because Jan is 0 (0-11)
            },
         },
         monthOfBirthShortWord: {
            get() {
               const nd = new Date(this.dateofbirth);
               return nd.toLocaleString('default', { month: 'short' });
            },
         }
      }     
   }
)

Then when you query them:

const document = await Listing.findById(id);
console.log(document.yearOfBirth);
// 1980
console.log(document.monthOfBirthDigit);
// 10
console.log(document.monthOfBirthShortWord);
// Oct