Run a function only if an object fetched from Auth0 includes the email property

  auth0, express, javascript, node.js, reactjs

Good Afternoon,

I am using the MERN stack and Auth0 for authentication. Right now what I want to happen is when the user logs on and the dashboard opens it loads their invoices, but as it stands right now I have to refresh the page once in order to get the invoices because on the initial load of the page the user object from Auth0 doesn’t exist, I get ‘cannot read property ’email’ of undefined’.

Architecture:

send user object to backend –> use app.set() to save the request –> on client have a function that makes call to a different endpoint that uses app.get() to get the user.

The above is very simplified, but I am not sure how to do an auto reload when new data is sent to backend (I have nodemon for changes). I have a useEffect() to make call to backend with user object and it watches and changes in the Auth0 user, I also setstate that will only run the second function if its true. The second function outside of the useEffect() is what gathers the invoices from the backend.

This is just an MVP so my architecture is not final.

// Reactjs 

// functions 
  async function fetchUserInvoices() {
    // Making a call to external api
    await fetch(`${process.env.REACT_APP_FETCH_USER_INVOICES}`)   
    .then(async (res) => {
      // Saving response to the invoiceResponse variable
      invoiceResponse = await res.json();
      console.log(invoiceResponse);
      
    }).catch(err => err);

      // Updating state to contain our object which is an array of objects
      setData(invoiceResponse);
 }



  // send user data to a test endpoint in the backend (WORKS)
  async function clientCall(info) {
    const url = `${process.env.REACT_APP_SAVE_USER}`;
    const axiosConfig = {
      method: 'post',
      url,
      data: info
    };
    await  axios(axiosConfig).catch((e) => {console.log(e)});
  }

 useEffect(() => {

    if(user !== undefined && user.hasOwnProperty('email') ) {

      clientCall(user);
      setUserInfo(true);
    }
  }, [user])
  
  if(userInfo) {

    fetchUserInvoices();
  }
  
  
  // Backend endpoints 
  userInvoices.get('/fetchUserInvoices', async (req,res) => {

  try {

    const invoices = await InvoiceModel.find().catch((e) => {console.log(e)});
    const user =  await app.get('Users');

    await matchUserAndInvoice(invoices,user);
    
    const userInvoices =  await app.get('userInvoices')
    res.json(userInvoices);

  } catch (error) {
    console.log(error)
  }

    
  });

 

  userInvoices.post('/saveUser', async (req, res) => {
    try {

      const User =  req.body;
 

      const  usersFromDB = await fetchUsersFromDB().catch((e) => {console.log(e)});
      findCommonUser(usersFromDB,User);
       app.set('Users', User)
      
    } catch (error) {
      console.log(error)
    }
    
    // functions for backend
       function findCommonUser(dbUser, User) {
  
      if(dbUser.length <= 0) {
  
        UserModel.create(User, () => {console.log('Users saved to database')});
        console.log('An Error has occured with Database')
        
      } else {
          dbUser.forEach((DBElement) => {
            
            
              if(User.email !== DBElement.email) {
                
                saveUser(User);
                
              } 
          })
      }
      console.log(' Users match')
  
    };

function matchUserAndInvoice(dbInvoices, loggedInUser) {
    let newArray = [];
    
    dbInvoices.forEach((DBElement) => {

      if(DBElement.customer_email === loggedInUser.email){

        newArray.push(DBElement);
        app.set('userInvoices', newArray);
      }
    })

  }
 
  // Main server.js
  const express = require('express');
const cors = require('cors');
const path = require('path');
const app = express();
const axios = require('axios');
const mongoose = require('mongoose');
const InvoiceModel = require('./models/Invoice');
require('dotenv').config()

//Routers
const HomeRouter = require('./Routes/HomeRoute');
const StoreInvoiceRouter = require('./Routes/Store-Update-Invoices');
const UserInvoicesRouter = require('./Routes/GetUserInvoices');
const SaveUserRouter = require('./Routes/SaveLoggedInUser');
const UpdateUserProfileRouter = require('./Routes/UpdateUserProfile');
const RedirectToResetPasswordRouter = require('./Routes/RedirectToResetPassword');


app.use(express.json());
app.use(cors());
app.use(express.static(path.join(__dirname, 'build')));


async function connectToDB() {
  
  // Database 
  await mongoose.connect(process.env.mongo_url, { useNewUrlParser: true, useUnifiedTopology: true },  () => {
    
    console.log('Connected to DB'); 
    
  });
  
  }
  connectToDB();

            // Function makes call to endpoint that runs deletion login, this allows the client to only have to be refreshed once to
            // render changes on the frontend.
            async function clientCall() {
              
              const url = `http://localhost:8080/store-update-invoices`;
              const axiosConfig = {
                method: 'get',
                url
                };
                await  axios(axiosConfig).catch((e) => {console.log(e)});
              };

              
    async function fetchInvoicesFromDB() {

    const invoicesFromDB = await InvoiceModel.find().catch((e) => {console.log(e)});
    return invoicesFromDB;
  };

  async function saveInvoicesToServer() {

    var  InvoicesResponse = await fetchInvoicesFromDB().catch((e) => {console.log(e)});
    app.set('Invoices', InvoicesResponse);
  }



  // Backend Routes
  app.use('/', HomeRouter);
  app.use('/', StoreInvoiceRouter);
  app.use('/', UserInvoicesRouter);
  app.use('/', SaveUserRouter);
  app.use('/', UpdateUserProfileRouter);
  app.use('/', RedirectToResetPasswordRouter);

 
   

            //// FUNCTION EXECUTIONS TO AND FROM DB //////

    // Function fetches stored invoices from DB and saves them to a variable and returns the variable so data can be accessed outside of function
   fetchInvoicesFromDB()
    .then(() => {

    // Function takes invoices from DB and saves them to app.set() in order to be used by other routes.
    saveInvoicesToServer();

    }).catch((err) => {console.log(err)});


  
  
  // Supporting functions
  clientCall();


  app.listen(process.env.PORT || 8080, () => {
  console.log(`Server listening on 8080`);
  });
  

Source: Ask Javascript Questions

LEAVE A COMMENT