Sort array of object by cascading priority of attributes interfaces

I want to sort an array of object (of the same interface) firstly sorting by one attribute of this interface, if these attributes are equals then sorting by secondly attribute, then sorting by a third attribute and so on.
And all in typescript mode.

My attempt solutions:

  1. Define the sorter:

    type Sorter = (a: T, b: T) => number;

Example:

const stateSorter = (aState: number, bState: number) => (bState < aState? -1 : 1);
const dateSorter = (aDate: Date, bDate: Date) => (aDate >= bDate ? -1 : 1);
  1. Define a sorter around attribute of a interface T

    interface SortSupplier<T, R> {
    supplier: (container: T) => R;
    sorter: Sorter< R >;
    }

Example:

interface StateAndDate {
  stateId: ClientStateIdEnum;
  registrationDate: Date;
}
const sorterBySupplier: SortSupplier<StateAndDate, Date> = {supplier: container => container.registrationDate, sorter: dateSorter}

First incorrect attempt:

Do by array of priority sort of SortSupplier:

const sortBySorters1 = <T>(a: T, b: T, orderedSorters: SortSupplier<T, any>[]): number => {
  let sortResult = 0;
  orderedSorters.some(supplierSorter => {
    sortResult = supplierSorter.sorter(supplierSorter.supplier(a), supplierSorter.supplier(b));
    return sortResult !== 0;
  });
  return sortResult;
}

and one wrong example is:

(a: StateAndDate, b: StateAndDate) => {
  return sortBySorters1(a, b, [
    {supplier: container => container.stateId, sorter: stateSorter},
    {supplier: container => container.registrationDate, sorter: stateSorter}
  ]);
}

It is wrong because the second sorter must sort by date but it accepts other different sorter, by number (state), due to the use of any as the second generic type of the SortSupplier

Second incorrect attempt:

Create a type of all possible attributes types of SortSupplier, for example, numbers and dates:

type SortSupplierType<T> = SortSupplier<T, Date>|SortSupplier<T, number>;

Then the previous incorrect sorter configuration:

{supplier: container => container.registrationDate, sorter: stateSorter} 

gives compilation error and the only compliance solution is the rigth one:

(a: StateAndDate, b: StateAndDate) => {
  return sortBySorters1(a, b, [
    {supplier: container => container.stateId, sorter: stateSorter},
    {supplier: container => container.registrationDate, sorter: dateSorter}
  ]);
}

But:

const sortBySorters2 = <T>(a: T, b: T, orderedSorters: SortSupplierType<T>[]): number => {
  let sortResult = 0;
  orderedSorters.some(supplierSorter => {
    sortResult = supplierSorter.sorter(supplierSorter.supplier(a), supplierSorter.supplier(b));
    return sortResult !== 0;
  });
  return sortResult;
}

But it gives the next compilation error:

Argument of type ‘number | Date’ is not assignable to parameter of type ‘Date & number’.

Type ‘number’ is not assignable to type ‘Date & number’.

Type ‘number’ is not assignable to type ‘Date’.

sortResult = supplierSorter.sorter(supplierSorter.supplier(a), supplierSorter.supplier(b));

¿Someone has a generalized solution to this sort problem around cascading priorioty sort of attributes interface?


(Sorry for my English)

How to add selectively create events & add event created / not created to my Google sheet?

I want to create a Google sheet that acts as “Scheduler + Logger” of all my meetings & calls.

To do this, I have a created a Google sheet containing all relevant information – I will enter event details & responses in it.

I want to create Google calendar events from this sheet with 2 criteria:

  • create only new events, not for rows for which events have been created previously
  • create events only for selected rows in Column B

Event should be created only those rows for which these 2 criteria are met.

I am attaching Sample Spreadsheet

I found an app script code & tried customizing it for my use case:

function create_Events(){

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Meetings / Calls");
  var last_row = sheet.getLastRow();
  var data = sheet.getRange("A2:P" + last_row).getValues();
  var cal = CalendarApp.getCalendarById("[email protected]");
  //Logger.log(data);

  for(var i = 0;i< data.length;i++){
    //index 0 =
    var event = CalendarApp.getDefaultCalendar().createEvent(
     data[i][2],
     new Date(data[i][12]),
     new Date(data[i][13]),
     {location: data[i][8],guests: data[i][3],sendInvites: true});
    sheet.getRange(i,16).setValues(event.getId());

    
  }

}

I am able to create events from this, but I am not able to do this –

  • Add success / failure message on each row when the event is created in Column P.
  • Create events only for selected rows in Column B when event has not been created previously as per Column P.

Please provide a solution.

How should I write Jest Test cases for styled component and spy on `:after` to verify if the styles apply correctly via props?

`I have developed the below component

// Button.js
import styled from ‘styled-components’;

const Button = styled.button`
position: relative;

&::after {
    content: '';
    position: absolute;
    width: ${props => props.width}px; /* Use the received width prop */
    /* other pseudo-element styles */
}

`;

export default Button;

I need to test the width changes correctly

BrowserRouter – React Router Dom: Stops navigating when deployed via CI

Set Up
Host: S3 bucket server through CloudFront
CI: Github Actions / Terraform
Cloudfront Custom error page 404 set to index.html (replaced with 200)
S3 Error Page set to index.js
React 18.2.0
React Router Dom 6.4.3 -> BrowserRouter Component

Very strange issue that has me stumped. When My React App is built and deployed via the CI. React Router will change the URL but not navigate to the correct screen. A hard refresh will go to the correct screen.

If I build Manually and Manually upload to S3 through the AWS console, navigation works as expected. Additionally navigation works all the time on localhost.

I can not figure out what the difference is, its stumped me for a few days. If anyone has any ideas it would really make my day.

CI is simply running npm install && npm run build

Here is the terraform resource thats depoying the files:

resource "aws_s3_bucket_object" "app_files" {
  for_each      = fileset("${path.module}/app/build", "**/*.*")
  bucket        = aws_s3_bucket.app_bucket.id
  key           = each.value
  source        = "${path.module}/app/build/${each.value}"
  etag          = filemd5("${path.module}/app/build/${each.value}")
  content_type  = lookup(var.mime_types, split(".", each.value)[length(split(".", each.value)) - 1], "application/octet-stream")
}

I have confirmed that mimetypes are being set properly.

here is my Cloudfront Distribution

resource "aws_cloudfront_distribution" "app_distribution" {
  origin {
    domain_name = aws_s3_bucket.app_bucket.website_endpoint
    origin_id   = aws_s3_bucket.app_bucket.id

    custom_origin_config {
      http_port = 80
      https_port = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols = ["TLSv1.2"]
    }
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }

  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"

  aliases = [var.service_domain]

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = aws_s3_bucket.app_bucket.id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 3600
    max_ttl                = 86400
  }

  viewer_certificate {
    acm_certificate_arn = var.main_certificate_arn
    ssl_support_method = "sni-only"
  }

  custom_error_response {
    error_code            = 404
    response_code         = 200
    response_page_path    = "/index.html"
    error_caching_min_ttl = 0
  }
}

Here is the JSX for my Router

<Router>
        <Routes>
          <Route // remove trailing slash
            path="*(/+)"
            loader={({ params }) => redirect(params['*'] || '/')}
          />
          {appStore?.auth?.accessToken ? (
            <Route path="" element={<Template />}>
              <Route
                exact
                path="/"
                element={<Navigate to={ROUTES.MY_MIRRORS} />}
              />
              ... Additional App Routes
              <Route
                path="/forbidden"
                element={<Pages.ErrorBoundaryForbidden />}
              />
              <Route path="/404" element={<Pages.ErrorBoundary404 />} />
              <Route
                path="*"
                element={<Navigate replace to={ROUTES.MY_MIRRORS} />}
              />
            </Route>
          ) : (
            <Route path="" element={<UnauthenticatedTemplate />}>
              <Route path="/login" element={<Pages.Login />} />
              <Route path="/register" element={<Pages.NewUser />} />
              <Route path="/contact" element={<Pages.Contact />} />
              <Route path="/privacy-policy" element={<Pages.PrivacyPolicy />} />
              <Route path="/" element={<Pages.Home />} />
              <Route path="*" element={<Navigate replace to="/login" />} />
            </Route>
          )}
        </Routes>
      </Router>

Finally, all navigation is used by the useNavigate hook:

import { useNavigate } from 'react-router-dom';
...

const navigate = useNavigate();
...
<Button color="gray" onClick={() => navigate('/contact')}>
  Contact Us
</Button>

How to turn an identifier into a string

Consider the following code:

class C {
  doSomething() {
    console.log('hello');
  }
}

const proxy = new Proxy({}, {
  get(target, prop) {
    return prop;
  }
});

const str = proxy.doSomething;

console.log(str);

const c = new C();
c[str]();

I have been able to turn the identifier doSomething into the string "doSomething".

This happens to be useful in situations when dealing with minified code, where I don’t know in advance what the identifier doSomething will be minified as.

Is there a way to obtain this string without using a Proxy?

Continuous / Synchronous communication between JavaScript and background program (C++ or shell)?

I’m trying to code a user vs. bot web app game. My bot’s logic is in C++, and I’d hate to rewrite it all in another language. It has multiple classes, header files, and methods,

I need some way to have a recurring (i.e. not one-time) channel of communication between the website (say, a JavaScript script) and my “background” program. Ideally, JS sends some info like a string (in this case, the user’s move) which is read via STDIN (std::cin); the program then processes it and returns a string response via STDOUT (std::cout), which JS can, say, display on the website. Notice that the background program needs to be kept alive in-between moves, waiting for the next user input. This is because the bot is keeping track of not just the current game state but also other things like history and paths it has already explored in the game theory tree.

I know about Emscripten, but I’ve only gotten it to work for one-time communications: the player triggers execution, upon which the C++ program starts, runs in its entirety and terminates. Different (entirely disjoint) processes are launched for each bot move, instead of a single root process handling all the heavy lifting, keeping the same memory stack in-between moves and possibly even using the user waiting time to think about its next move.

It might still be possible to do this with emscripten, but I haven’t found a way.

How can I get this to work? My final idea is Node.JS, which seems capable of running C++ modules, but I’m hesitant to use it since it seems like it has a steep learning curve.

EDIT: More context, to simplify things, imagine the website is super simple: an input box where the user writes some string, a Submit button, and a text box with the response: a concatenation of all the strings the user has submitted until now. So the C++ program in this case is very simple, it stores a vector (list) of all the previous strings, and when the user submits a new string, it appends it to the list, and returns the concatenation of the list.

How do I circumvent the same origin browser policy (CORS) using NODE JS?

I have 2 websites. (mydomain1.com, mydomain2.com) What I need to do is make the first site (mydomain1.com) load, with puppeteer, and then change its URL to that of the second site without reload page. I know that it is prohibited by browsers, but how i will do it with node JS, i will can to manipulate some things in browser.

Those are the browser configurations:

    var browser = await puppeteer.launch({
        headless: false,
        executablePath: executable,
        ignoreDefaultArgs: ["--enable-automation"],
    args: [
      '--disable-web-security',
      '--disable-features=IsolateOrigins,site-per-process',
      '--disable-site-isolation-trials',
      '--disable-features=BlockInsecurePrivateNetworkRequests',
      '--disable-features=SameSiteByDefaultCookies',
      '--disable-features=CookiesWithoutSameSiteMustBeSecure',

    ]

And this is my code

const page = await browser.newPage();
await page.goto('localhost/test.html')
  await page.evaluate(() => {
    document.domain = "example.com";
  });

But then return this error:
Uncaught DOMException: Failed to set the ‘domain’ property on ‘Document’: ‘example.com’ is not a suffix of ‘127.0.0.1’.

There is some way to configure my browser to ignore same origin policy?

moongose paginate doesn’t sort items

I’m working with moongose, express, handlebars and moongose-paginate-v2, I have an issue where I want products to render by price, the problem is that for some reason sort does not work, it doesn’t even throw an error, maybe I’m using it wrong? the render works properly, it just doesn’t bring my collection by price

router.get('/products', async (req,res)=>{
    const {limit, page, stock, category, sort} = req.query
    try{
        const products = await productService.getProductsByPagination(limit, page, stock, category, sort)
        products.stock = stock
        products.category = category

        res.render('products',products)
    } catch(err){
        res.send(err)
    }

})

this is my function:

async getProductsByPagination(limit = 10, page = 1, stock= false, category= false){
    let filter = {}
    let sort = {}

    if(stock){
        filter = { ...filter, stock }
    }

    if(category){
        filter = { ...filter ,category }
    }

    if(category || stock){
        sort = {price: 1}
    }

    return  this.model.paginate(filter, {lean: true, limit, page, sort})
}

NextJS 13 Dynamic Routes – Firebase Hosting Deployment issue

I have a problem with dynamic routes. I use App Routes from NextJs13 to define routes.

Here is my firebase.json code:

{
  "functions": [
    {
      "source": "functions",
      "ignore": [
        "node_modules",
        ".git",
        "firebase-debug.log",
        "firebase-debug.*.log"
      ],
      "predeploy": [
        "npm --prefix "$RESOURCE_DIR" run build"
      ]
    }
  ],
  "firestore": {
    "rules": "firestore.rules",
    "indexes": "firestore.indexes.json"
  },
  "hosting": {
    "source": ".",
    "cleanUrls": true,
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "frameworksBackend": {
      "region": "europe-west1",
      "maxInstances": 2
    },
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  },
  "storage": {
    "rules": "storage.rules"
  }
}

Here is next.config.js code:

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true,
    trailingSlash: true,
    experimental: {
        serverActions: true,
    },
}

module.exports = nextConfig

My dynamic path looks like this:
app/projects/[slug]/page.tsx

If i try to open this location on deployed website i see message:
Service Unavailable

Would you like to be kind and try to help me? Thank you 🙂

React button not adding component to the page

The Add item button should trigger a pop up form with input fields, but the form is not rendering. It shows blank page on rendering just with the button.


import './App.css';

const InventoryManager = () => {
  
        dispatch(addItem(newItem));

        // Reset the input fields
        setItemName('');
        setItemDescription('');
        setItemPrice('');
        setItemImage('');

        // Close the popup form
        setShowPopup(false);
    };

    const handleClearForm = () => {
        // Clear the input fields
        setItemName('');
        setItemDescription('');
        setItemPrice('');
        setItemImage('');
    };

    return (
        <div>
            <h1>Inventory Manager</h1>

            <div id="buttons">
                <button onClick={() => setShowPopup(true)}>Add Item</button>
            </div>

            {showPopup && (
                <div id="add-item-popup">
                    <div id="popup-header">
                        <h2>Add Item</h2>
                        <button id="close-button" onClick={() => setShowPopup(false)}>
                            X
                        </button>
                    </div>
                   
      
                    </form>
                </div>
            )}

            <div id="inventory-gallery">{/* Render inventory items here */}</div>
        </div>
    );
};

export default InventoryManager;

Tried implementing in a single file and in different component files but form still not rendering.

Safari Async pixel calls getting cancelled

In my application I have a code where I need to trigger an image pixel(tracking pixel) before redirecting user a different page. It works fine on all browsers but in Safari, for some reason the tracking pixels is not getting triggered. All the other pixels like landing page pixels work fine. Only the pixel that are supposed to trigger before redirecting to a different page are getting cancelled/not triggering. Does anybody else face this issue? if yes how did you solve it?
Also I cant throw a popup/alert as this tracking pixel needs to fire behind the scene without interrupting the user flow

Insert an id from table A into table B if data is or isn’t inserted into table A in mySQL?

I’ve been coding for about a year now and currently I’m working on a portfolio piece (a recipe website) but I’m stuck and not sure how to proceed.

My problem is that I need to figure out a way to take the auto incremented id of the ingredient from table A whether inserted or not (if already in database) and insert it into table B.

When a recipe is submitted, I have my code set up so that it checks my ingredients table for the ingredient submitted using the following mySQL query.

SELECT 
        i.ingredient
    CASE
        WHEN 
            LOWER(?) = LOWER(ingredient) 
            THEN INSERT IGNORE INTO 
                i (ingredient) VALUES ?
        ELSE 
            LOWER(?) != LOWER(ingredient)
            THEN INSERT INTO
                i VALUES ?
    END
FROM
    ingredients i

I originally tried using an after insert trigger but realized that won’t work if the ingredient is already in the database and not newly inserted. Because of this I think my approach may need to be refactored.

My goal is for when the recipe is submitted the ingredients are compiled into an array using:

let ingredients = req.body.ingredients;
    let ingredientArray = Array();
    ingredients.forEach(ingredient => {
        ingredientArray.push([ingredient.ingredient]);
    });

Then the mySQL query runs and either inserts the ingredient into table A or ignores if already present. Following either of those options then the auto incremented id of the ingredient is inserted into table B. To make it more complicated recipe_id would be pulled in from Table C (contains various other recipe information), amount would be the value typed in by the user into the input field (turned into an array), and unit_id would be a unit selected by the user which corresponds to a set predefined list of measurements already in the database (also turned into an array). Both of these arrays would use the same JavaScript code above to make them arrays.

Table A looks like:

id ingredient
1 Sugar
2 Flour

Table B looks like:

id recipe_id amount unit_id ingredient_id
1 45 1 5 1
2 76 4 4 2

Check if an element exists of another array of objects

I have the two following Arrays of objects.

const respProducts = [
    {
        "cursor": "eyJsYXN0X2lkIjo4OT234234sYXN0X3ZhbHVlIjo4OTkzOTgyMjExfQ==",
        "node": {
            "id": "gid://shopify/Product/8923422211",
            "title": "California Here"
        }
    },
    {
        "cursor": "eyJsYXN0X2lkIjo5234234sYXN0X3ZhbHVlIjo5MDExNDM0MzA3fQ==",
        "node": {
            "id": "gid://shopify/Product/923423434307",
            "title": "Texas 2000 Here"
        }
    },
    {
        "cursor": "eyJsYXN0X2lkIj234234LCJsYXN0X3ZhbHVlIjo5MzM4MDczODcwfQ==",
        "node": {
            "id": "gid://shopify/Product/23423470",
            "title": "Texas Black Here"
        }
    }
]

const currentTemplates = {
    "Texas 2000 Here": {
        "productTemplate": {
        },
        "colorVariants": false
    },
    "Alabama": {
        "productTemplate": {
        },
        "colorVariants": false
    },
    "Alaska": {
        "productTemplate": {
        },
        "colorVariants": false
    },
    "Arizona": {
        "productTemplate": {
        },
        "colorVariants": false
    }
}

I need to check if an item from respProducts is found in currentTemplates if so do not return it if it is found then return it. I need respProducts to retain it’s structure.
Only remove any items that are in currentTemplates.

My attempt:

const respBuildArray = respProducts.filter(el => el.node.title.includes(Object.keys(currentTemplates).map(el => el)));

In the above example I would like to get back:

const respBuildArray = [
    {
        "cursor": "eyJsYXN0X2lkIjo4OT234234sYXN0X3ZhbHVlIjo4OTkzOTgyMjExfQ==",
        "node": {
            "id": "gid://shopify/Product/8923422211",
            "title": "California Here"
        }
    },
    {
        "cursor": "eyJsYXN0X2lkIj234234LCJsYXN0X3ZhbHVlIjo5MzM4MDczODcwfQ==",
        "node": {
            "id": "gid://shopify/Product/23423470",
            "title": "Texas Black Here"
        }
    }
]

since Texas 2000 Here is in currentTemplates.
My above code returns an empty array.