Using mongoose findbyid with express to get object from database only works with callback? Callbacks importance in newer js frameworks?

I’m doing the express local library tutorial on MDN docs and wanted to experiment returning an object without using a call back method.

When passing in the request object parameter for the id to the the findById mongoose method like so var bookinstance = BookInstance.findById(req.params.id); and log to the console, this is the contents of bookinstance:

BookInstance.findOne({ _id: '63e17d2395d1d4e11604cf22' })

When passing the id and a callback function to the findById method like so

BookInstance.findById(req.params.id, function(err, instance) {
      if (err) {
         next(err);
      }
      console.log('findById callback: ' + instance);
      res.render("bookinstance_delete", {
         title: "Book Instance Delete",
         id: instance._id,
         imprint: instance.imprint,
         book: instance.book
      })
   })

and log to console, the expected book instance object is outputted:

findById callback: {
  _id: new ObjectId("63e17d2395d1d4e11604cf22"),
  book: new ObjectId("63e17d2395d1d4e11604cf16"),
  imprint: 'New York Tom Doherty Associates, 2016.',
  status: 'Available',
  due_back: 2023-02-06T22:20:19.928Z,
  __v: 0
}

Is this something to do with javascript in general? This is the first time i’ve been exposed to express, node, mongoose, and all these javascript based frameworks and technologies, and they all seem to use callbacks quite heavily. Is the purpose of callbacks just to have a way to say, hey execute this task, and when you’re finished, do this task?

When I didn’t use the call back, the object returned is the object and method(findone), when executed, would give me the bookinstance object and properties. So the callback function would take that object as the instance parameter, execute it and return the object? Is that what is going on?

Typescript property reference inside a property [duplicate]

I have a property declared below:

export const properties = {
  username: 'admin',
  password: 'pass',
  environment: 'test1',
  // Trying to construct the url so it becomes http://test1.com
  url: 'http://'  + environment + '.com',

};

I would like to reuse environment inside the url value. However it can’t seem the find it. I have tried the following and had no luck:

url: 'http://'  + environment + '.com',
url: 'http://'  + this.environment + '.com',
url: 'http://'  + properties.environment + '.com',

Does anyone have any idea on how it can be done? Thank you

Turning a .then / .catch block of code into Async Await

to preface this, as I’m sure this will be a walk in the park for 99% of you guys, I’m quite new to JS and want to ensure I’m using all the syntactic sugar that I can to be up-to-date when the time comes for interviews and job prep etc.

As such, I was hoping someone would kindly help me turn the below app.post request, from a Promise .then, into an async / await (try, catch) function.

As a side-note, this small block is forming a very basic user authentication to a Mongo DB. I have a block of code that’s for a new user to register, and I can write that with async / await just fine. I’m struggling with this part somehow.

app.post("/login", (req, res) => {
  const username = req.body.username;
  const password = req.body.password;
  User.findOne({ email: username })
    .then((foundUser) => {
      if (foundUser.password === password) {
        res.render("secrets");
      }
    })
    .catch((err) => {
      console.log(err);
    });
});

I have essentially tried writing this a number of times and keep rendering the (err) instead of the page I want.

Make custom tooltip for FullCalendar.js

I try to make custom tooltip for events in FullCalendar.js but I dont know how can i do that;

this is my code when mouseEnter to event

eventMouseEnter: function(event, jsEvent) {
    var tooltip = `
      <div id="custom-event-tooltip-popup" class="md-tooltip" id="tooltip" style="display: none;direction:rtl;position: absolute">
               <div class="md-tooltip-info"
                    style="height: 121px;background-color: #FFFBF5;position: relative;border-color: #FFFBF5 !important;">
                    <div id="div-color" style="position: absolute;right: 0;width: 4px;height: 90px;border-radius: 8px;"></div>
                         <p id="tooltip-event-time" class="md-tooltip-time"
                            style="font-size: 10px;color: #A3A3A4;display: block;margin-top: 20px;position: absolute;"></p>
                    <div class="d-flex justify-content-between align-items-center">
                         <span id="tooltip-event-name-age" class="md-tooltip-name-age"
                               style="font-size: 12px;color: #757575;margin-top: -30px;"></span>
                                <div id="tooltip-image" style="background-image: url('/indexImages/projectIcon/Rectangle 2564.png');background-repeat: no-repeat;background-position: center;background-size: cover;height: 41px;width: 37px;border-radius: 8px"></div>
                         </div>
                         <div class="md-tooltip-title" style="font-size: 12px;color: #757575;">
                              مدرس دوره: <span id="tooltip-event-title" class="md-tooltip-status md-tooltip-text"></span>
                         </div>
                    <div class="md-tooltip-title" style="font-size: 12px;color: #757575;">نحوه برگزاری: <span id="tooltip-event-reason" class="md-tooltip-reason md-tooltip-text"></span></div>
               </div>
      </div>
    `;
},

Re-enable default vertical scroll after horizontal scroll completes

so I am stuck with this functionality where I want to create a section with horizontal scrolling in between normal and vartical sections

For the page building I am using visual composer for scroll I used this code of javascript:

<script>
document.addEventListener("DOMContentLoaded", function() {
  const containers = document.querySelectorAll('.sticky-container .wpb_wrapper');
  console.log('Containers found:', containers);

  if (containers.length === 0) {
    console.log('No containers found, please check the querySelector.');
  }

  containers.forEach(function(container) {
    container.addEventListener("wheel", function (e) {
     
        if (e.deltaY > 0) {
       
        container.scrollLeft += 100;
        e.preventDefault();
      } else {
        container.scrollLeft -= 100;
        e.preventDefault();
      }
    });
  });
})
</script>

The above code works fine until you reach sticky-container and it scrolls the content horizontally but the problem arises when the content has finished scrolling it won’t go ahead to next section or I’d say doesn’t enable vertical scroll.

My website: https://bananablossom.niceone.digital/?salient_g_sections=horizontal-scrolling-by-jashua

I also this codepen https://codepen.io/alvarotrigo/pen/VwWMjVp but it isn’t useful with Visual Composer rows.

Please note there are many solutions but I am using visual composer and that is making the real difficulty.

Vue 3 modal/drawer with transition and v-if

I have the following code that renders a modal

<EditUserModal :key="`EditUserDrawer-${selectedUser.id}`" :user="selectedUser" :opened="modalIsShowing"/>

This is the modal content (simplified, showing only the props)

<script setup lang="ts">

const props = defineProps({
    opened: {
        type: Boolean
    },
    user: {
        type: Object as PropType<User>,
        required: true
    }
})

I’m getting an error saying Type User | undefined is not assignable to type User
Now the solution I was thinking of, and I know is wrong, was to add v-if="selectedUser" to the element, making it look like this: Because of the use of v-if, this causes the modal to not animate open.

<EditUserModal v-if="selectedUser" :key="EditUserDrawer-12" :user="selectedUser" :opened="modalIsShowing"/>

Is there a method in Vue 3 that allows me to not send undefined to this modal, without having to use v-if?

How can we implement search on the encrypted data in mongoDB database?

I am using the mongoose-field-encryption package which allows me to encrypt and decrypt the data before storing and accessing it. The encrypted fields are name, email and number.
I need to implement search functionality for the encrypted fields directly in the query itself.

import crypto from 'crypto'
import mongoose, { Schema } from 'mongoose'
const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
import { encryptionSecret } from '../../config'

const userSchema = new Schema({
  email: {
    type: String,
    match: /^S+@S+.S+$/,
    required: true,
    unique: true,
    trim: true,
    lowercase: true,
    index: true,
  },
  name: {
    type: String,
    trim: true
  },
  contactNumber: {
    type: String,
    default:null
  }
}, {
  timestamps: true
})

userSchema.plugin(mongooseFieldEncryption, { 
  fields: ["email", "contactNumber"], 
  secret: encryptionSecret,
  saltGenerator: function (secret) {
    return "1452819847269312";
  },
});


const model = mongoose.model('User', userSchema)

export const schema = model.schema
export default model

import { User } from '.'

export const getUsers = async (req, res) => {
    try {

        let { email } = req.query

        if (email) {
            const messageToSearchWith = new User({ email });
            messageToSearchWith.encryptFieldsSync();

            query.email = messageToSearchWith.email
        }

        
        let users = await User.find(query)

        return res.status(200).json(users)

    } catch (error) {
        console.log('error in getting users', error)
    }
}

Above is the model and the function. Encrypted data is stored in the database but I am not able to search on the same.

I tried logging the encrypted fields, the email being saved and the encrypted email in the logs are coming out to be different. These should be same for the exact match.

I need to search over the encrypted email

Please let me know what needs to be modified to make this work as per expectations.

sql Average according to the value

INSERT INTO `iot_athlete_ind_cont_non_cur_chlng_consp` (`aicicc_id`, `aicid_id`, `aicidl_id`, `aica_id`, `at_id`, `aicicc_type`, `aicicc_tp`, `aicicc_attempt`, `pan_percentile`, `age_percentile`, `aicicc_lastposition`, `aicicc_status`, `created_at`, `updated_at`) VALUES
(198, 414, 709, 8, 263, 'Time', '25', 1, NULL, NULL, 12, 'Active', '2023-04-25 11:31:22', '2023-04-25 11:57:28'),
(199, 414, 709, 69, 263, 'Reps', '22', 1, NULL, NULL, 33, 'Active', '2023-04-25 11:32:18', '2023-04-25 11:57:44'),
(200, 414, 709, 8, 263, 'Time', '21', 2, NULL, NULL, 12, 'Active', '2023-04-25 11:33:02', '2023-04-25 11:57:48'),
(201, 414, 709, 69, 263, 'Reps', '36', 2, NULL, NULL, 33, 'Active', '2023-04-25 11:33:24', '2023-04-25 11:57:52'),
(202, 414, 709, 8, 263, 'Time', '26', 3, NULL, NULL, 12, 'Active', '2023-04-25 11:33:42', '2023-04-25 11:58:01'),
(203, 414, 709, 69, 263, 'Reps', '20', 3, NULL, NULL, 33, 'Active', '2023-04-25 11:33:54', '2023-04-25 11:58:07'),
(204, 414, 709, 8, 263, 'Time', '19', 4, NULL, NULL, 12, 'Active', '2023-04-25 11:34:08', '2023-04-25 11:58:13'),
(205, 414, 709, 69, 263, 'Reps', '16', 4, NULL, NULL, 33, 'Active', '2023-04-25 11:34:21', '2023-04-25 11:58:18'),
(206, 414, 709, 8, 263, 'Time', '13', 5, NULL, NULL, 12, 'Active', '2023-04-25 11:34:43', '2023-04-25 11:58:22'),
(207, 414, 709, 69, 263, 'Reps', '33', 5, NULL, NULL, 33, 'Active', '2023-04-25 11:34:54', '2023-04-25 11:58:27'),
(208, 414, 710, 8, 276, 'Time', '3', 1, NULL, NULL, 12, 'Active', '2023-04-25 11:37:13', '2023-04-25 11:54:25'),
(209, 414, 710, 69, 276, 'Reps', '56', 1, NULL, NULL, 33, 'Active', '2023-04-25 11:39:51', '2023-04-25 11:54:32'),
(210, 414, 710, 8, 276, 'Time', '22', 2, NULL, NULL, 12, 'Active', '2023-04-25 11:40:56', '2023-04-25 11:54:45'),
(211, 414, 710, 69, 276, 'Reps', '20', 2, NULL, NULL, 33, 'Active', '2023-04-25 11:41:09', '2023-04-25 11:55:13'),
(212, 414, 710, 8, 276, 'Time', '21', 3, NULL, NULL, 12, 'Active', '2023-04-25 11:41:19', '2023-04-25 11:55:18'),
(213, 414, 710, 69, 276, 'Reps', '25', 3, NULL, NULL, 33, 'Active', '2023-04-25 11:41:31', '2023-04-25 11:55:24'),
(214, 414, 710, 8, 276, 'Time', '20', 4, NULL, NULL, 12, 'Active', '2023-04-25 11:41:44', '2023-04-25 11:55:28'),
(215, 414, 710, 69, 276, 'Reps', '26', 4, NULL, NULL, 33, 'Active', '2023-04-25 11:41:58', '2023-04-25 11:55:33'),
(216, 414, 710, 8, 276, 'Time', '50', 5, NULL, NULL, 12, 'Active', '2023-04-25 11:42:25', '2023-04-25 11:55:45'),
(217, 414, 710, 69, 276, 'Reps', '49', 5, NULL, NULL, 33, 'Active', '2023-04-25 11:42:35', '2023-04-25 11:55:49');

I need attempt(aicicc_attempt) wise average.
value for calculation of average=aicicc_tp;

where at_id=263 aica_id=8 and 69 and aicicc_attempt=1,(25+22)=average will be 23.5
again where at_id=263 aica_id=8 and 69 and aicicc_attempt=2, (21+36)=average will be 57
again where at_id=263 aica_id=8 and 69 and aicicc_attempt=3, (26+20)=average will be 23
again where at_id=263 aica_id=8 AND 69 and aicicc_attempt=4, (19+16)=average will be 17.5
again where at_id=263 aica_id=8 AND 69 and aicicc_attempt=5, (13+33)=average will be 23

for multiple at_id;
where at_id=276 aica_id=8 and 69 and aicicc_attempt=1, (3+56)=average will be 29.5
again where at_id=276 aica_id=8 and 69 and aicicc_attempt=2, (22+20)=average will be 21
again where at_id=276 aica_id=8 and 69 and aicicc_attempt=3, (21+25)=average will be 23
again where at_id=276 aica_id=8and 69 and aicicc_attempt=4, (20+26)=average will be 23
again where at_id=276 aica_id=8and 69 and aicicc_attempt=5, (50+49)=average will be 49.5

I am using this query for calculation of percentage-I need one more column for average.
SELECT *,percent_rank() OVER (ORDER BY convert(aicicc_tp, decimal) ASC ) AS prcnt_rank FROM iot_athlete_ind_cont_non_cur_chlng_consp where aicid_id = ‘414’ ORDER BY iot_athlete_ind_cont_non_cur_chlng_consp.aicicc_attempt ASC;

How can i revalidate cached data in Next 12?

There’s a Next.js 13 feature that allows revalidate fetched data after some time:

const results = fetch(url, {
  cache: "force-cache",
  next: {
    revalidate: 10
  }
})

I have an advanced project and i wouldn’t like to migrate to Next.13

There’s some way to achieve the next: {revalidate: 10} behavior on Next 12 and pure js?

NOTE: this fetch call can be done multiple times, depending on the user’s actions, so I can’t use getStaticProps or the like. I understand that those functions allows fetch data only once

How can I settle the matter: “Uncaught TypeError: Cannot read properties of null (reading ‘addEventListener’) “?

I write on Vanilla JS and have more than one page. On the main page I don’t have this mistake, but it is on the other pages.

Here you are the code, and a bold string which is lighten in the code. In my opinion it tells me about variable “choiceAll”, that I have only on the main page.

***choiceAll*.addEventListener('click', function(){**
    choiceCat.forEach(function(item){
        item.classList.remove('hide')
    })

I have read messages with answers. For exapmle, two of them –

1.
 if(choiceAll){
     console.log('button seen')
 }else{
     console.log('button not seen')
 }

2.
 try{
     checkchoiceAll.addEventListener('click', function(){
        console.log('result');
     });
 } catch(error){
     console.log(error);
     }

And I still have the message about mistake in console.

CORS blocking get request in code but directly accessing endpoint returns data

I have an angular front end website that is trying to hit an endpoint on a webserver. At this point the website is in a proof of concept phase. Here’s the request:

constructor(private http: HttpClient) { }

getData(): Observable<any> {
    const headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': 'http://localhost:4200'
    });
    return this.http.get(`${this.apiUrl}`, { headers: headers, withCredentials: true}); }

When I directly paste the endpoint URL into the browser I get an XML response with the data. So what is wrong with the request that it is blocked by CORS when running through my webpage but if I paste the URL in the same browser it returns a result?

Month and Year in jQuery datepicker is not displayed correctly in update form

I am using jQuery (jui) date picker extension in Yii 2 form. I have a table in the database which stores the StartYear and EndYear. StartYear and EndYear are having varchar datatype.
For example: StartYear : June 2023 and EndYear : April 2024

I have configured the datepicker to show only months and year. Data is correctly getting saved in create action. But in the update action, incorrect values are getting displayed in StartYear and EndYear fields.

Below is the _form.php

<?php

use yiihelpersHtml;

use yiibootstrapActiveForm;
use yiijuiDatePicker;
use yiihelpersArrayHelper;

/* @var $this yiiwebView */
/* @var $model appmodelsAcademicyear */
/* @var $form yiiwidgetsActiveForm */
?>

<style type="text/css">
.ui-datepicker-calendar {
        display: none;
    }
</style>


<script>

$(document).ready(function() {
    $('.picker').datepicker({
     changeMonth: true,
     changeYear: true,
     dateFormat: 'MM yy',

         onClose: function() {
        var iMonth = $("#ui-datepicker-div .ui-datepicker-month :selected").val();
        var iYear = $("#ui-datepicker-div .ui-datepicker-year :selected").val();
        $(this).datepicker('setDate', new Date(iYear, iMonth, 1));
     },



});
});
</script>
  <?php $form = ActiveForm::begin()?>
<div class="row">
<div class="col-sm-5">
 <?= $form->field($model, 'StartYear')->widget(DatePicker::classname(), [
                                            //'language' => 'ru',

                                            'options' => ['class' => 'form-control picker','readOnly'=>'readOnly'],
                                            'clientOptions'=>['changeMonth'=>true,
                                            'changeYear'=>true,
                                            'dateFormat' => 'MM yy',
                                            'readOnly'=>true]

]) ?>
</div>
    </div>
<div class="row">
<div class="col-sm-5">
 <?= $form->field($model, 'EndYear')->widget(DatePicker::classname(), [
                                            //'language' => 'ru',
                                            'options' => ['class' => 'form-control picker','readOnly'=>'readOnly'],
                                            'clientOptions'=>['changeMonth'=>true,
                                            'changeYear'=>true,
                                            'dateFormat' => 'MM yy',
                                            'readOnly'=>true]
]) ?>
</div>
</div>
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
  <?php ActiveForm::end(); ?>

How can I display elements from an array of strings only if their length is greater then zero in this app?

I am working on an SPA with Vue 3, TypeScript and The Movie Database (TMDB).

The app displays list of movie cards.

In the MoviesList component (srccomponentsMoviesList.vue), I have:

<template>
    <div class="row list">
            <div v-for="movie in movies" :key="movie.id" class="col-xs-12 col-sm-6 col-lg-4 col-xl-3">
                <MovieCard :movie="movie" :genres="genres" />
            </div> 
  </div>
</template>

<script lang="ts">
    import { defineComponent, ref } from 'vue';
    import axios from 'axios';
    import env from '../env';
    import MovieCard from './MovieCard.vue';

    export default defineComponent({
        name: 'MoviesList',
        components: {MovieCard},
        props: {
            listType: String
        },

    data() {
      return {
        pageTitle: "Now Playing",
        movies: [],
        genres: [],
      }
    },

    mounted() {
      this.getMovies();
      this.getGenres();
    },

     methods: {
      getMovies() {
        axios.get(`${env.api_url}/movie/${this.$props.listType}?api_key=${env.api_key}`).then(response => {
          this.movies = response.data.results;
        })
        .catch(err => console.log(err));
      },

      getGenres() {
        axios.get(`${env.api_url}/genre/movie/list?api_key=${env.api_key}`).then(response => {
          this.genres = response.data.genres;
          console.log(this.genres);
        })
        .catch(err => console.log(err));
      }
    }
  });
</script>

In the MovieCard component (srccomponentsMovieCard.vue), I have:

<template>
    <div class="movie card">
        <div class="thumbnail">
            <img :src="`https://image.tmdb.org/t/p/w500/${movie.backdrop_path}`" :alt="movie.title" class="img-fluid" />
        </div>

        <div class="card-content">
            <h2 class="card-title">{{ movie.title }}</h2>
            <p class="card-desc">{{ movie.overview }}</p>
            <span :title="`Score: ${movie.vote_average}`" class="score d-flex">{{ movie.vote_average }}</span>
        </div>

        <div class="card-footer">
            <p class="m-0 release">Release date: {{ dateTime(movie.release_date) }}</p>
            <p class="m-0 pt-1">
                <a class="genre" v-for="genre in movie.genre_ids" :key="genre.id">
                    {{ getGenreName(genre) }}
                </a>
            </p>
        </div>
    </div>
</template>

<script lang="ts">
  import { defineComponent } from 'vue';
  import moment from 'moment';

  export default defineComponent({
    name: 'MovieCard',

    props: {
        movie: {
            type: Object,
            required: true
        },

        genres: {
            type: Object,
            required: true
        }
    },
    
  methods: {
    dateTime(value: any) {
            return moment(value).format('MMMM DD, YYYY');
        },

        getGenreName(gid: number) {
            if (this.genres[gid]) {
                if (this.genres[gid].name.length) {
                    return this.genres[gid].name;
                }
            }
        }
    },
  });
</script>

The problem

I use the below condition to make sure no empty genre conrainers are displayed:

if (this.genres[gid].name.length) {
    return this.genres[gid].name;
}

For a reason I have been unable to understand, this fails, as seen below.

enter image description here

Questions

  1. What is my mistake?
  2. What is the most reliable way to get the desired result?