Supabase: Filter data with join and logical ‘OR’

I’m using Supabase as a database and trying to implement a full-text search.

My example setup is quite simple, I have two tables:

items

+----+-----------+-----------------+
| id | name      | manufacturer_id |
+----+-----------+-----------------+
| 1  | Notebook  | 1               |
+----+-----------+-----------------+
| 2  | Mouse     | 2               |
+----+-----------+-----------------+

manufacturers

+----+-----------+
| id | name      |
+----+-----------+
| 1  | Apple     |
+----+-----------+
| 2  | Microsoft |
+----+-----------+

My goal: search for item names or manufacturer names and always receive the respective items. Searching for ‘Apple’ would return all items whose manufacturers name contain this phrase. Searching for ‘Notebook’ would return all items with this name.

(I simplified this example by using exact matches because this is not the problem I’m stuck with).

My current approach is the following:

let keyword = 'Apple';

supabase
  .from('items')
  .select('*, manufacturers!inner(*)')
  .or(`name.eq.${term}`)
  .or(`name.eq.${term}`, { foreignTable: 'manufacturers' })

Although this query does not return anything.

If I remove .or('name.eq.${term}') it return the correct item. Same if I remove the second .or() and use an item name as my keyword.

I simply can’t find a way to combine two OR operators. I also tried multiple filter() queries but was not successfully.

Does anyone have an approach on how to do that? Thank you in advance!

mock service worker, sad path test failure

Recently just using Mock Service Worker to test my HTTP requests, i’m looking to test my failure path.

My first test passes (happy), but the error i’m receiving for my failure is “Unexpected end of JSON input”

It does behave in the way that I would like, but from a testing point of view i’m a little confused.

If anyone knows how I can get my failure path to pass it would be great.

My test file

import "whatwg-fetch";
import { rest } from "msw";
import { setupServer } from "msw/node";

import { collect } from "./collect";

const server = setupServer(
  rest.get(
    "http://api.openweathermap.org/data/2.5/weather",
    (req, res, ctx) => {
      return res(
        ctx.status(200),
        ctx.json({ base: "stations", clouds: { all: 6 }, cod: 200 })
      );
    }
  )
);

beforeAll(() => server.listen());
afterAll(() => server.close());
afterEach(() => server.resetHandlers());

it("collects data", async () => {
  const res = await collect();
  expect(res).toEqual({ base: "stations", clouds: { all: 6 }, cod: 200 });
});

it("handles failure", async () => {
  server.use(
    rest.get(
      "http://api.openweathermap.org/data/2.5/weather",
      (req, res, ctx) => {
        return res(ctx.status(401));
      }
    )
  );
  await expect(collect()).rejects.toThrow("401");
});

My fetch async function

require('dotenv').config()

export const collect = async () => {
    const key = process.env.REACT_APP_API_KE
    // try{
      const res = await fetch(`http://api.openweathermap.org/data/2.5/weather?q=london&appid=${key}`)
      if(res.status !== 200){
        const error = await res.json()
        throw { message: error.message, status: error.cod }
      }
        const data = await res.json()
        return data 
}

Custom closing operation on javascript [duplicate]

Hi i’m using the following script to itercept the closing event in javascript:

window.addEventListener('beforeunload', function(e) {           
        e.preventDefault();
        e.returnValue = '';         
    });

But it intercept all the event that make the program leaving the page. I want to perform this operation only on closing call(like tab/browser closing) but not in the program function (I.E. login/logout). There is a way to perform this?
Is also possible to gain the response of the user to the popup message?
Thanks

I would like to have help reformatting this, I can not load this into a button without reformatting it

I would like to have help reformatting this, I cant find a easy way to do so.

"use strict";

// import { Workbox } from 'https://storage.googleapis.com/workbox-cdn/releases/4.0.0/workbox-window.prod.mjs';

// to invoke emulator API //

$(function () {
    var embeddedEmulator = window.emulator = new V86Starter({
        wasm_path: "build/v86.wasm",
        memory_size: 64 * 1024 * 1024,
        vga_memory_size: 2 * 1024 * 1024,
        screen_container: document.getElementById("emb_container"),
        bios: {
            url: "bios/seabios.bin",
        },
        vga_bios: {
            url: "bios/vgabios.bin",
        },
        cdrom: {
            url: "build/embedded.iso",
        },
        filesystem: {
            //basefs: "tools/fstest.json",
            //baseurl: "/mnt/",
        },
        autostart: true,
        //disable_keyboard: true,
    });

    // File upload //
    $(function () {
        $('#uploadfs').on('change', function () {
            for (var i = 0; i < $(this).get(0).files.length; i++) {
                var fileName = $(this).get(0).files[i].name;
                writeFile($(this).get(0).files[i], fileName);
            }
            function writeFile(inputFile, fileName) {
                var reader = new FileReader();
                reader.readAsBinaryString(inputFile);
                reader.onload = function () {
                    var output = reader.result;
                    var buffer = new Uint8Array(output.length);
                    buffer.set(output.split("").map(function (chr) { return chr.charCodeAt(0); }));
                    embeddedEmulator.create_file(fileName, buffer, function (error) {
                        if (error) throw error;
                    });
                }
            }

        });
    });

    // File download //
    $(function () {
        $('#downloadfs').on('keypress', function (e) {
            var inputFile = this.value;

            if (e.which == 13) {
                embeddedEmulator.read_file(inputFile, function (error, uint8array) {
                    if (error) throw error;
                    if (uint8array) {
                        var fileName = inputFile.replace(//$/, "").split("/");
                        fileName = fileName[fileName.length - 1];
                        downloadFile(fileName, String.fromCharCode.apply(this, uint8array))
                    }
                });
            }
            function downloadFile(fileName, content) {
                var a = document.createElement("a");
                a.download = fileName;
                a.href = window.URL.createObjectURL(new Blob([content]));
                a.dataset.downloadurl = "application/octet-stream:" + a.download + ":" + a.href;
                a.click();
            }
        });
    });

    var lastTick = 0;
    var uptime = 0;
    var lastInstrCount = 0;
    var totalInstructions = 0;

    embeddedEmulator.add_listener("emulator-started", function () {
        var start = Date.now();
        console.log('instruction counter' + this.v86.cpu.instruction_counter[0]);
        var instructionCount = embeddedEmulator.get_instruction_counter();
        //console.log('instru conu ' + instructionCount);
        if (instructionCount < lastInstrCount) {
            // 32-bit wrap-around
            lastInstrCount -= 0x100000000;
        }

        var last_ips = instructionCount - lastInstrCount;
        lastInstrCount = instructionCount;
        totalInstructions += last_ips;

        var delta_time = start - lastTick;
        //console.log('delta' + delta_time);
        uptime += delta_time;
        //console.log('up' + uptime);
        lastTick = start;

        setInterval(function () {
            document.querySelector('#uptime').textContent = format_timestamp((Date.now() - start) / 1000 | 0);
        }, 999);
        setInterval(function () {
            document.querySelector('#speed').textContent = (last_ips / 1000 / delta_time).toFixed(1);
        }, 999);
        setInterval(function () {
            document.querySelector('#avg_speed').textContent = (totalInstructions / 1000 / uptime).toFixed(1);
        }, 999);
    });


    function format_timestamp(time) {
        if(time < 60)
              {
                  return time + "s";
              }
              else if(time < 3600)
              {
                  return (time / 60 | 0) + "m " + (time % 60) + "s";
              }
              else
              {
                  return (time / 3600 | 0) + "h " +
                      ((time / 60 | 0) % 60) + "m " +
                      (time % 60) + "s";
              }
          }

//}

// nohost browser Filesystem //

 // if ('serviceWorker' in navigator) {
   //  const wb = new Workbox('../build/nohost-sw.js?debug');

     // Wait on the server to be fully ready to handle routing requests
     //wb.controlling.then(serverReady);



     //wb.register();
   //}
    
});


I am trying to build a version of GitHub.com/copy/v86
based on a fork called v86_support
using the API built by Copy
a cdrom upload would be nice
i am trying to make this work for my emu-compute project

I tried reformatting the JavaScript and it crashed

How to highlight a view for a specific duration in React Native ScrollView

I have developed a Chat App using React Native, I have also implemented a feature which is present in WhatsApp & other Chat Apps -> if a message is a reply of a particular message, if we tap on it, it will scroll us to that specific message just like shown in the image below. Now, I have managed to develop the scrolling feature when a reply message is pressed, but unable to highlight that view of message for a particular duration like WhatsApp does. How can I implement the same?

Repied message highlight image

MessageItem.js

const MessageItem = ({
  message,
  scrollViewRef,
  replyMessageIndex,
}) => {

  return (
    <TouchableOpacity>
      {message.reply && (
        <TouchableOpacity
          style={styles.replyContainer}
          onPress={() => {
            scrollViewRef.current.scrollTo({
              animated: true,
              y: replyMessageIndex,
            });
          }}>
          <Text>{message.reply.text}</Text>
          )}
        </TouchableOpacity>
      )}
      <Text>{message.text}</Text>
    </TouchableOpacity>
  );
};

ChatScreen.js -> ScrollView didn’t include all the code because it was a large file.

<ScrollView
            ref={scrollViewRef}
            showsVerticalScrollIndicator={false}>
            {messages.length > 0 ? (
              messages.map((message, index) => {
                // finding the replied message if it is present. No problem here, working fine.
                let replyMessageIndex = null;
                if (message.reply) {
                  replyMessageIndex = messages.findIndex(
                    msg => msg._id === message.reply._id,
                  );
                }
                return (
                  <MessageItem
                    key={index}
                    message={message}
                    scrollViewRef={scrollViewRef}
                    replyMessageIndex={replyMessageIndex}
                  />
                );
              })
            ) : (
              <View style={styles.noChatContainer}>
                <Text style={styles.noChatText}>Start Chatting</Text>
              </View>
            )}
          </ScrollView>

So, as I said earlier, how can I actually highlight the scrolled message for, like a second so that user gets to know that “oh it was a reply to this message”. I am able to scroll to that message but not animate/highlight it.

Any solution would be really appreciated!

Typescript: only name/destructure optional properties when taking an interface parameter?

I’m new to typescript and am writing some classes to work as a very simple ORM for my project. I just learned how to require that a parameter conform to an interface, like so:

interface UserInfo {
    userId: string
    email?: string
    // many more properties...
}
class User {
    constructor(connection: typeof db, init: UserInfo) {
    // code here

And I understand that the syntax to set default values for those optional properties is:

class User {
    constructor(connection: typeof db, {email = null, /*...*/}: UserInfo) {
    // code here

But my UserInfo interface is long, what if I want to only specify/default a few of the properties, without typing out a giant object in the parameters for the constructor of this object? Is there a way to require an entire interface, but destructure only some properties?

Same GA ClientID for multiple users

We collect GA ClientIDs from the forms that are submitted on our websites and write them into hidden fields so we can use them in Google Analytics.

Lately, I have noticed that 55 users have exactly the same GA ClientID as each other and given that this number is a Browser/Device pair with the last 8 digits after the . being a timestamp, how on earth could this be happening?

My first thought was a Bot until I noticed that one of the test submissions was ME and it was using that same ID.

Any theories or thoughts would be much appreciated.

How to setup correctly on the site CookieConsent v2.7.1 by orestbida.com

I was trying to insert this feature into a website created with a drag & drop program (WebSite X5 Builder Incomedia). The basic program allows you to insert JS, CSS and HTML code into the page.

Generally, I just put the code in the tag etc. and everything works. Could someone please help me?

Source:

https://github.com/orestbida/cookieconsent

https://orestbida.com/demo-projects/cookieconsent/

How do I create a vertical scroll mousewheel function (jQuery)?

I’ve created this script:

jQuery(".resultlist").mousewheel(function(event, delta) {
  this.scrollLeft -= (delta);
  event.preventDefault();
});

which fires a horizontal scroll function over the .resultlist container and this is working as expected. I need to disable this on screen widths underneath 545px so I’ve wrapped it in a resize function.

/* Trigger Resize Script */
jQuery(document).ready(function(){
    function resizeForm(){
        var width = (window.innerWidth > 0) ? window.innerWidth : document.documentElement.clientWidth;
        if(width > 545){
            jQuery(".resultlist").mousewheel(function(event, delta) {
              this.scrollLeft -= (delta);
              event.preventDefault();
            });
        } else {
            // invert
        }    
    }
    window.onresize = resizeForm;
    resizeForm();
});
/* End Trigger Resize Script */

The problem I have is that the script still runs if else is true, I did start working on a function that would include and then delete a separate script based on screenwidth but this became very cumbersome and is surely not the right way to achieve this.

I need to convert the mousewheel function so that it behaves like a normal vertical scroll instead, so that I can switch between my current horizontal scroll and a normal vertical scroll inside the resize function.

How do I amend the below function to scroll vertically?

jQuery(".resultlist").mousewheel(function(event, delta) {
   this.scrollLeft -= (delta);
   event.preventDefault();
});

How do I write a function to return the contents from a node http.request

Not sure why this synchronous/asynchronous stuff is so confusing to me.
I have a node/electron project, and I simply need to hit a url with a post and return the contents.

(pseudo code)

// do https.request post
function getPage(url) {
  do a POST to http.request and grab the contents of url
  then RETURN the contents
}

// get page
var cont = getPage('example');

do something with cont :)

for each object array, how to add a field into it?

What I want is to insert a field index into my array

My code thar I receive my arrays is like that:

  const onFinish = (values) => {
      console.log(values.fields);

     addFields({ formName: 'TABLE NAME', fields: values.fields }).then(() => {
       //API CALL WHICH RETURNS A RESPONSE
     });
   };

values.fields is the array that I want to make it work

values.field array :

[
    {
        "field": "Peso do bezerro (kg)",
        "fieldtype": "Numeric"
    },
    {
        "field": "test",
        "fieldtype": "Text"
    },
    {
        "field": "Obs",
        "fieldtype": "Text"
    }
]

This array can have ‘x’ objects,What I want is for each add a field named index(which will get if it's the first and add 0 if the second will add a 1 and following...).Someone knows how to make it work ?

enter image description here

Why vue 3 import all js files for all pages on first load project

Vue 3 import all js files for all vue components on first load project.
i want vue to import only required files.
for example if i open contact page vue 3 should import only contact.js file.
Right now it is import all those files

<link href="/js/contact.js" rel="prefetch">
<link href="/js/forgot.js" rel="prefetch">
<link href="/js/signin.js" rel="prefetch">
<link href="/js/signup.js" rel="prefetch">
<link href="/js/app.js" rel="preload" as="script">
<link href="/js/chunk-vendors.js" rel="preload" as="script">

These my index router file :

import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
import store from "../store";
import {authConstants} from "../_constants";

const routes = [
    {
        path: "/",
        name: "Home",
        component:()=>Home,
    },
    {
        path: "/contact",
        name: "contact",
        component: () => import(/* webpackChunkName: "contact" */ "../views/contact.vue"),
    },
    {
        path: "/signin",
        name: "signin",
        component: () => import(/* webpackChunkName: "signin" */ "../components/auth/signin.vue"),
    },
    {
        path: "/signup",
        name: "signup",
        component: () => import(/* webpackChunkName: "signup" */ "../components/auth/signup.vue"),
    },
    {
        path: "/recoverpassword",
        name: "recoverPassword",
        component: () => import(/* webpackChunkName: "forgot" */ "../components/auth/recoverPassword.vue"),
    },
];

const router = createRouter({
    history: createWebHistory(process.env.BASE_URL),
    routes,
    scrollBehavior() {
        // document.getElementById("app").scrollIntoView();
    },
});

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        // this route requires auth, check if logged in
        // if not, redirect to login page.
        if (!store.getters[authConstants.GET_USER_DATA]) {
            next({ name: 'signin' })
        } else {
            next() // go to wherever I'm going
        }
    } else {
        next() // does not require auth, make sure to always call next()!
    }
})

export default router;

and thanks for help in advanced.

Vue3 – watching changes on all variables in component at once instead of each one?

I have a few variables in my component. For example:

const selectedStudents = computed({
get: get it
set: { set it; search(); }

const selectedTeachers = computed({
get: get it
set: { set it; search(); }

const selectedSchools = computed({
get: get it
set: { set it; search(); }

I am wondering if it’s possible to make it so that instead of having the search(); in every set function, I somehow watch changes on ANY of the variables, and if any of them changes, I perform a search. The reason I want this is because currently, in certain situations, I perform as many searches as I have variables (7-8 currently), when it could just be one search instead.

NodeJS – Close Pg DB Pool on Process Exit

I’ve written the following code to ensure my pg-db pool is closed in the event of the process exiting.

['exit', 'SIGINT', 'SIGUSR1', 'SIGUSR2', 'uncaughtException', 'SIGTERM'].forEach(ev => { 
     process.on(ev, cleanUp.bind(null, ev));
});

where cleanUp is defined as follows:

let didEnd = false

function cleanUp(options, exCode) { 
  try {
   if (!didEnd) { 
     didEnd = true
     console.log('closing pool')
     pool.end(() => {}))
   }
  } catch(ex) { 
   process.exit(1)
}

I’ve noticed that when this code executes, the closing pool string is logged and the process seems to hang and not terminate gracefully when this code executes. Shouldn’t the exit signal continue to execute once the cleanUp method runs, terminating the process?