Firebase & Javascript – Sorting Data Using Firestore Queries Conditionally Through Dropdown Menu

While creating a project got stuck at a point. I want to sort the data according to the particular item selected from dropdown menu. I want to replace the first argument of onSnapshot function (colRef) with query variables conditionally.

The code relevant to the problem :-

data :

books(collection)
  document-1(doc)
    {
      "title": "title-1",
      "rating": 4.0,
      "year" : xxxx,
      "createdAt": created time
    }
  document-2(doc)
    {
       ....
       ....
    }

index.html :

<div class="sort-dropdown">
    <button>Alphabetical Order</button>
    <button>Rating</button>
    <button>Date</button>
    <button>Recent Book</button>
</div>

db.js :

// Initialize services
const db = getFirestore()

// collection reference
const colRef = collection(db, 'books')

// query references
const q1 = query(colRef, orderBy('title'))
const q2 = query(colRef, orderBy('rating'))
const q3 = query(colRef, orderBy('date'))
const q4 = query(colRef, orderBy('createdAt'))

// Getting realtime collection data
onSnapshot(colRef, (snapshot) => {
  snapshot.docChanges().forEach(change => {
    if(change.type === 'added'){
      renderList(change.doc.data(), change.doc.id);
    }
  })
})

const renderList = (data, id) => { ... using some dom elements to display data }

this returns undefined: (node:3196) UnhandledPromiseRejectionWarning: TypeError: Cannot read property ‘myArray’ of undefined

Here’s my code:

https://github.com/DavidNyan10/NewProject

const fs = require('fs');
const csv = require('csv-parser')

const myString = new Promise((resolve, reject) => {
    resolve('John');
});

class myClass{
    constructor(filename){
        this.myArray = [];
        this.myArray.push(new Promise((res) => {
            fs.createReadStream('filename')
                  .pipe(csv(['FirstName', 'LastName', 'Address', 'Town', 'Country', 'Postcode']))
                  .on('data', (data) => {
                    return(data);
                  })
          }))
    }
    async myFunction() {
        for(let i = 0; i < this.myArray.length; i++) {
            if (myString.includes(this.myArray[i]['phrase'])){
                if (this.cooled_down(i)){
                    this.approve(i, myString);
                }
            }
        }
    }
    
    cooled_down(i){
        dictionary = this.myArray[i]
        if (!dictionary.keys().includes('approved')){
            // Means we have never approved on this person!
            return True;
        } else{
            now = datetime.now();
            duration = now - datetime.fromtimestamp(dictionary['approved']);
            duration_seconds = duration.total_seconds();
            hours = divmod(duration_seconds, 3600)[0];
            if (hours >= 24){
                return True;
            } else{
                console.log("Couldn't approve " + dictionary['FirstName'] + "Cool Down time: " + 24 - hours);
            }
        }
        return False;
    }

    approve(i, myString){
        dictionary = this.myArray[i];
        try{
            setTimeout(function(){
                console.log(myString);
                console.log(dictionary['FirstName'])
                console.log(dictionary['Postcode'])
            }, 60 * 60 * 3);
        }catch(e){
            console.log(e);
        }

        now = datetime.now();
        this.myArray[i]['approved'] = now.timestamp();
    }
}

myObj = new myClass("myCSV.csv");
myString.then(myObj.myFunction);

It keeps saying

(node:3196) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'myArray' of undefined
    at myFunction (D:projectsnewprojectindex.js:20:30)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:3196) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:3196) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

But as you can clearly see, this.myArray is clearly defined well on line 10.

What is going on?

I’m pretty new to javascript classes and objects, so I’m sorry if I looks dumb.

Also, any ideas how i can make line 11-17 better? I’m just putting the csv into an array but I don’t know if that’s the best way to do it.

Change the scroll bar width, color and height of specific container with overflow property

I want to change the width color and height of the scroll bar only of my sidebar in the dashboard. I have seen in the many pages that browser scrollbar and specific container(with overflow property) differs. when i try to change the scroll bar property of it, browsers scrollbar changes too. So anybody please help me to change the propety of specific container scrollbar. Thankyou.

How do array equals useState declarations work in Javascript?

In functional components within ReactJS, the following line allows the creation of:

  1. A variable to record the current count
  2. A method to save the state when called

Example in JS:

let [count, setCount] = useState([]);

How does this work from a declaration point of view and what is this kind of declaration called?

I understand basic declarations like let array = []; etc but am not familiar with the other way around.

Creating an optimized build freezes and never completes

I am trying to build my react app. But when I run “npm run build”, The terminal freezes on “Creating and optimized production build…” and never finish.
This is my JSON file. I tried on 16 GB ram also.

I have deleted package lock file and also rebuild the dependencies. But it remains same.
There is no specific solution anywhere, if anyone has solution please let me know.

{
  "name": "demoapp",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@emotion/react": "^11.4.1",
    "@emotion/styled": "^11.3.0",
    "@material-ui/core": "^4.12.2",
    "@material-ui/data-grid": "^4.0.0-alpha.33",
    "@material-ui/lab": "^4.0.0-alpha.60",
    "@mui/material": "^5.0.3",
    "@progress/kendo-drawing": "^1.16.0",
    "@progress/kendo-licensing": "^1.2.1",
    "@progress/kendo-react-pdf": "^4.12.0",
    "@progress/kendo-theme-material": "^4.43.0",
    "@progress/kendo-ui": "^2021.3.1109",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "axios": "^0.21.1",
    "bootstrap": "^5.0.2",
    "chart.js": "^3.5.0",
    "dom-to-pdf": "^0.2.2",
    "draft-js": "^0.11.7",
    "draftjs-to-html": "^0.9.1",
    "html-to-draftjs": "^1.5.0",
    "pdf-viewer-reactjs": "^2.2.3",
    "react": "^17.0.2",
    "react-app-polyfill": "^2.0.0",
    "react-chartjs-2": "^3.0.4",
    "react-csv": "^2.0.3",
    "react-dom": "^17.0.2",
    "react-draft-wysiwyg": "^1.14.7",
    "react-hook-form": "^7.10.1",
    "react-icons": "^4.2.0",
    "react-loader": "^2.4.7",
    "react-loader-spinner": "^4.0.0",
    "react-modal-video": "^1.2.8",
    "react-redux": "^7.2.4",
    "react-responsive-carousel": "^3.2.21",
    "react-router-dom": "^5.2.0",
    "react-scripts": "^4.0.3",
    "react-table": "^7.7.0",
    "reactstrap": "^8.9.0",
    "redux": "^4.1.0",
    "redux-thunk": "^2.3.0",
    "sweetalert2": "^11.0.18",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "ie 11",
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

jsignature – issue utilizing multiple colors on the canvas and exporting a svg

I’m using jSignature, which is a jQuery plugin for adding web signature functionality. I’m trying to allow the user to utilize multiple colors on the canvas and export a svg file. The issue is the user can utilize multiple colors on the canvas, however each time they change colors (with the class “changeColor” the variable “data”, which contains the data needed to save the svg is reset and thus it doesn’t match the canvas.

jSignature library: https://github.com/brinley/jSignature

After each color change data resets to:

image/svg+xml,<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="0" height="0"></svg>

My code:

<td style='background:#f0e4b0;id="#f0e4b0" class='changeColor'></td>
<td style='background:#b6e61e;id="#b6e61e" class='changeColor'></td>

<div id="signature"></div>
<textarea id='output' name='sig'></textarea>

<button id="clear">Clear</button>
<button type="button" onclick="download()">Save</button>

 <script>
        $(document).ready(function() {
            // Initialize jSignature
            var pen = '#000000';
            var $sigdiv = $("#signature").jSignature({
                'UndoButton' : false,
                'color' : pen
            });

$('.changeColor').on('click', function(event) {
         //   $('#signature').jSignature("reset");
    pen = $(this).attr('id');
    //update settings 
    $("#signature").jSignature('updateSetting', "color", pen,true);

  });

            $('#clear').click(function () {
            $('#signature').jSignature("reset");
            });

            $('#signature').change(function() {    
                var data = $sigdiv.jSignature('getData', 'svg');
                // Storing in textarea
                $('#output').val(data);

                // Alter image source 
                $('#sign_prev').attr('src', "data:" + data);
                $('#sign_prev').show();
            });
        });
    </script>

<script>
function download(){
    var text = document.getElementById("output").value;
    var blob = new Blob([text], { type: "text/plain"});
    var anchor = document.createElement("a");
    anchor.download = "signature.svg";
    anchor.href = window.URL.createObjectURL(blob);
    anchor.target ="_blank";
    anchor.style.display = "none";
    document.body.appendChild(anchor);
    anchor.click();
    document.body.removeChild(anchor);
 }
</script>

Understanding featured based arquitecture in React

I’m implementing an ecommerce in react with a feature-based architecture but I dont know where to place those functionalities that are shared between features but are specific enough to belong to a feature and not to a common folder, like auth or cart features.

I have an Auth feature where I put components like login or resetPassword and are isolated in an Auth folder, but I need things like useAuth hook to verify if a user is authenticated in any place in the aplication.

setState in useEffect not working in conjunction with localStorage

This seems unordinary. I’m attempting to simply setState on mount, but it’s just going blank on me.

const [info, setState] = useState({
    user_1: '',
    user_2: '',
});

useEffect(() => {

    var personal_1 = window.localStorage.getItem('personal_1');
    var personal_2 = window.localStorage.getItem('personal_2');
    console.log(personal_1);
    if (personal_1 !== null && personal_2 !== null) {
        console.log('Make it easy')
        setState({
            ...info,
            user_1: personal_1,
            user_2: personal_2
        })
    }

}, [])

useEffect(() => {
    console.log('User personal_1 was changed to', info.user_1);
}, [info.user_1])

When I log the effects of this component mounting,
it shows

personal_1
Make it easy
User personal_1 was changed to

For some reason instead of setting the state on mount to the value from local storage, it just goes blank. I thought it was probably being set back to being blank from somewhere else in the component, but the info.personal_1 hook only gets called once. Does anyone know why it might potentially be setting the local storage item, but then going blank when the storage item is a normal string?

Are two actions/reducers with the same name permissible in two different reducer files?

I’m curious about something. I was always under the impression that one could have two actions with the same name in two different reducers and that Redux would sort out the correct one to call.

So for example, say you had this setup:

  • Reducer1: with an UPDATE_TEXT reducer
  • Reducer2: with an UPDATE_TEXT reducer

And then in your React component file, when you load the correct actions file, it would just know which reducer to call. But testing reveals this not to be the case.

Am I imagining things? Is there a way to isolate and remove such conflicts? Or does one have to carefully never give two disparate reducers the same action name?

Azure Devops widget using azure-devops-extension-api to fetch all Pull requests by project only fetching one result

I am trying to create a azure devops widget to pull all PRs associated with the project . The widget is working but only pulling one PR data and not all. Below is the widget code I am using

        VSS.require(["TFS/Dashboards/WidgetHelpers","TFS/VersionControl/GitRestClient"], 
        function (WidgetHelpers, TFS_Wit_WebApi) {
            WidgetHelpers.IncludeWidgetStyles();
            VSS.register("PRDuration", function () {                
            var projectId = VSS.getWebContext().project.id;

                var getQueryInfo = function (widgetSettings) {
                    // Get a WIT client to make REST calls to Azure DevOps Services                       
                   return TFS_Wit_WebApi.getClient().getPullRequestsByProject(projectId,"status: All ",null,0,100)
                        .then(function (prs) {
                            var $list = $('<ul>');
                            prs.forEach(function(pr) {                             
                            
                            //$list.append($('<li>').text("Project ID: " + projectId));
                            //$list.append($('<li>').text("Pull Request ID: " + pr.pullRequestId));
                            $list.append($('<li>').text("Pull Request title: " + pr.title));
                            $list.append($('<li>').text("Pull Request createdBy: " + pr.createdBy))
                            $list.append($('<li>').text("Pull Request creationDate: " + pr.creationDate));
                            $list.append($('<li>').text("Pull Request closedDate: " + pr.closedDate));
                            ;
                            //$list.append($('<li>').text("Query Name: " + query.name));
                            //$list.append($('<li>').text("Created By: " + (query.createdBy ? query.createdBy.displayName: "<unknown>") ));
                            })

                            // Append the list to the query-info-container
                            var $container = $('#query-info-container');
                            $container.empty();
                            $container.append($list);

                            // Use the widget helper and return success as Widget Status
                            return WidgetHelpers.WidgetStatusHelper.Success();
                        }, function (error) {
                            // Use the widget helper and return failure as Widget Status
                            return WidgetHelpers.WidgetStatusHelper.Failure(error.message);
                        });
                }

                return {
                    load: function (widgetSettings) {
                        // Set your title
                        var $title = $('h2.title');
                        $title.text('Hello World');

                        return getQueryInfo(widgetSettings);
                    }
                }
            });
        VSS.notifyLoadSucceeded();
    });   

When I used this widget it seems to be making below API call and fetching just one result :
https://dev.azure.com/orgname/projectId/_apis/git/pullRequests?searchCriteria=status:All&api-version=6.0

If I am changing the api URL as below then I get all the results :
https://dev.azure.com/orgname/projectId/_apis/git/pullRequests?searchCriteria.status=All&api-version=6.0

Is there a way I can fix this in search criteria of function getPullRequestsByProject to get all results?