Shopify dynamic metafields for product when it’s a 404 (Liquid nested in Liquid?)

Whenever a URL results in a 404, I have a javascript that fires that redirects conditionally to a relevant URL.

This has worked great for some time.

But now I want to be able to redirect specific products that have been Drafted… to specific redirect URLs using metafields.

WHAT I HAVE DONE :
I have successfully allowed administrators to enter a URL in a metafield (redirect_url).

And I have been able to output that to the product page :
{{ product.metafields.custom.redirect_url.value }}

And I have been able to pass that to javascript :
const redirect_url = "{{ product.metafields.custom.redirect_url.value }}"; console.log(redirect_url); // output : the correct redirect URL

BUT… the metafields are NOT available when the product is Drafted and results in a 404…

BUT I have discovered you can access metafields even when not on that product page… like this :
{{ product['example-product-handle'].metafields.custom.redirect_url.value }}

but I need something dynamic…

{{handle}} is available and valid… and this would be golden :
const redirect_url = "{{ product['{{ handle }}'].metafields.custom.redirect_url.value }}";

but that breaks and the result is a mangled string 🙁

so i’m up against the wall with this and seeking help… I would really appreciate any solutions anyone has to offer!

To reiterate the goal :
I need to be able to access the metafields of a product even when it’s a 404. Normally, Shopify provides access to the metafileds easily, but NOT when it’s a 404.

So I want to be able to take the available data {{ handle }} and use it to access the metafields

I also want to avoid using Shopify Redirects because I want to make it easier and convenient for content administrators by being able to change the redirect URL themselves inline on the Edit Product screen.

Desynchronizing Gif’s

I don’t know how to desynchronize this two gif’s.

I tested it in opera and edge browser.

When I am starting first gif (left), I expect that second one will start it’s own animation.
They should be desynchronized. But they aren’t.

Second one is starting in middle of the animation. In exactly the same moment, in which first one currently is.

<!DOCTYPE html>
<html lang="en">
<head>
    <title>gif desynchronization</title>
</head>
<body>
    <div id="gif1"></div>
    <div id="gif2"></div>
</body>
</html>
<style>
    #gif1,#gif2
    {
        position: fixed;
        width: 100px;
        height: 100px;
        left: 0;
        top: 0;
        background-color: red; 
        background-size: 100% 100%;
    }
    #gif2
    {
        left: 110px;
    }
</style>
<script>
    function show1()
    {
        let gif1Element = document.getElementById("gif1")
        setTimeout(
            () => {gif1Element.style.backgroundImage = 'url(boom.gif)'},0
        )
    }
    show1()
    function show2()
    {
        let gif2Element = document.getElementById("gif2")
        setTimeout(
            () => {gif2Element.style.backgroundImage = 'url(boom.gif)'},400
        )
    }
    show2()
    //how it is possible that #gif2 doesn't started it's own gif-animation?
    //they are both using the same gif, from the same "stream"?
</script>

here you can download my gif: link

  • I was trying to use <img> tag, but result was exactly the same.

  • I heard that i need to reset source of an element.

    but i think that shouldn’t be looking like this:

    function restartGif(img) 
    {
      let src = img.src;
      img.src = '';
      img.src = src;
    }
    

I just want to add that I apologize for my English. I’m still learning

How to create such a diagram in Chart.js?

I am trying to create this diagram with Chart.js.

Challenges:

  • As you see on the x-axis are categories. I want the point to be placed in the middle.
  • I want the value to be on top of the point.

enter image description here

My code so far:

        new Chart(ctx, {
        type: 'line',
        data: {
            labels: ['Buy', 'Sell'],
            datasets:
                [
                    ...grid.pairs.map(pair => {
                        return {
                            data: [pair.buyPrice, pair.sellPrice],
                            borderColor: '#0d6efd',
                            backgroundColor: '#0d6efd',
                            pointRadius: [3, 5],
                        }
                    }),
                    {
                        label: 'Market Price',
                        data: [grid.marketPrice, grid.marketPrice],
                        borderColor: 'red',
                        backgroundColor: 'red',
                    }
                ]
        },
        options: {
            scales: {
                x: {
                },
                y: {
                    title: {
                        display: true,
                        text: 'Price in Euro'
                    },
                }
            },
        }
    })

May I get some help with this?

Kendo Grid not Displaying Inside of a Popup Window

The partial view below successfully displays a Kendo Grid, provided it is not contained inside of a KendoPopup Window. The data for this grid is stored in a variable present in the view’s model.

// ImportGroupAddressPopup.cshtml
@model AddressData

<div id="GroupAddressPopup">
    <div class="row" style="padding-top: 20px">
        <div class="col-md-12">
            <div class="row">
                <div class="col-md-11" style="padding-left: 4.7em">


                    @(Html.Kendo().Grid(Model.groupAddresses)
                        .Name("groupAddresses")
                        .HtmlAttributes(new { style = "width:100%; padding-left:1em" })
                        .ToolBar(t =>
                        {
                            t.ClientTemplateId("GridToolbarTemplate");
                        })
                        .Columns(columns =>
                        {
                            columns.Bound(obj => obj.Address1).Title("Address").Width(260);
                            columns.Bound(obj => obj.AddressCity).Title("City").Width(50);
                            columns.Bound(obj => obj.State).Title("State").Width(10);
                            columns.Bound(obj => obj.ZipCode).Title("Zip Code").Width(50);
                            columns.Bound(obj => obj.County).Title("County");

                        })

                        .Sortable(sortable => sortable
                        .AllowUnsort(true))
                        .Resizable(resizable => resizable.Columns(true))
                        .Navigatable()
                        .Filterable()
                        .Scrollable()
                        .Resizable(resize => resize.Columns(true))

                        )

                </div>
            </div>
        </div>
    </div>
</div>
// AddressOverview.cshtml 

...
    <div id="GroupAddressPopup-Container" style="display:none;">
        @await Html.PartialAsync("~/Views/Shared/EditorTemplates/ImportGroupAddressPopup.cshtml", this.Model);
    </div>
...

 <button type="button" class="k-button k-button-icontext" onclick="openGroupImportPopup()"><span class="k-icon k-i-add"></span>Insert From Group</button>

...

<script>
    var groupAddressPopupForm = $("#GroupAddressPopup");
    var title = "Import Addresses from Affiliated Group";
    groupAddressPopupForm.kendoWindow({
        width: "75%",
        modal: true,
        resizable: false,
        title: title,
        visible: false,
        actions: ["Close"]
    });

    var importGroupAddressPopup = groupAddressPopupForm.data("kendoWindow");

    function openGroupImportPopup() {
        importGroupAddressPopup.center().open();
        importGroupAddressPopup.title("Import Addresses from Affiliated Group");
    }
    function closeGroupAddresspopup() {
        importGroupAddressPopup.close();
    }

</script>

Placing the code responsible for the grid outside of the popup results in a grid displaying data as expected. I have set a breakpoint in the grid code configured inside the popup window and confirmed that the model variable containing the data is indeed valid.

Why would this grid function outside of a popup window, but not inside of one?

React.js switch case always returns default case

I am trying to use <select> tags to update information between components with the help of useContext(). The problem that I am facing is that the default case is always returned despite the console.log matching the set case values.

The renderer for the different selects.

const selectNames = [
     "Strength",
     "Dexterity",
     "Constitution",
     "Intelligence",
     "Wisdom",
     "Charisma"
]

const options = [
        {
            label: '16',
            value: '16'
        },
        {
            label: '14',
            value: '14-1'
        },
        {
            label: '14',
            value: '14-2'
        },
        {
            label: '12',
            value: '12-1'
        },
        {
            label: '12',
            value: '12-2'
        },
        {
            label: '10',
            value: '10'
        }
    ]

const selectRender = selectNames.map((name, index) => {
   return (
      <>
         <label for={name}>{name}:</label>
         <select name={name} key={index} onChange={handleChange} value={chosenOptions[name] || ''}
                 required={index === 0} id={name.toLowerCase()}>
              <option value=''/>
              {options.filter(({value}) => !isChosenByOther(value, name))
                   .map(({label, value}, oIndex) =>
                        <option value={value} key={oIndex}>{label}</option>)
               }
         </select>
     </>
   )
})

Here’s the code for the event handler function containing the switch case.

The setStrength() and other like functions are the de-structured functions from the context component and I believe are referenced correctly. Additionally, if there is a problem with them I don’t think it would matter for this specific issue as the code never calls them.

const handleChange = (ev) => {
        setChosenOptions({...chosenOptions, [ev.target.name]: ev.target.value});
        console.log(ev.target.name)
        switch (ev.target.name) {
            case "Strength":
                setStrength(ev.target.value)
            case "Dexterity":
                setDexterity(ev.target.value)
            case "Constitution":
                setConstitution(ev.target.value)
            case "Intelligence":
                setIntelligence(ev.target.value)
            case "Wisdom":
                setWisdom(ev.target.value)
            case "Charisma":
                setCharisma(ev.target.value)
            default:
                console.log("attribute wasn't successfully changed")
        }
    };

Whenever I select values within the react app it correctly references the specific <select> I change but always calls the default function.

The console logs:

Intelligence

attribute wasn't successfully changed

Charisma

attribute wasn't successfully changed

Wisdom

attribute wasn't successfully changed

Let me know if you need to see different sections of code and what not.

Create an If Statement which uses 2 criteria to sort serial numbers in javascript?

I’m currently beginning a Javascript coding course. One task requires me to check if a serial number is valid, and if it is, add it to an array to store all valid serial numbers.

The serial numbers must be:

  • odd numbers
  • contain 6 digits

Here is my current code:

--------------------------

function findEfficientBulbs(serialNumbers) 
{
    console.log(serialNumbers);
    const efficientSerialNumbers = [];


for (let i = 0; i < serialNumbers.length; i++) 
{
    let currentNumber = serialNumbers[i]
    if (currentNumber % 2 === 1 && currentNumber.length === 6)
    {
        efficientSerialNumbers.push(currentNumber)
    }
};
    return efficientSerialNumbers;
}

------------------------------------

according to the platform, this code is not removing the even numbers, error message below:

‘should keep all efficient numbers – those that are odd and have six digits in

✕ AssertionError: expected [] to deeply equal [ 234567, 456789 ]

logs

[ 123456, 234567, 345678, 456789 ]’

Have tried as above, as well as nested If Statements

500 (Internal Server Error) on GET, POST requests to Function App Azure

I created the Function App, I created a Function named HttpTrigger and provided the code in the index.js file which is the following:

const { performance, promisify } = require('perf_hooks');
const fs = require('fs');
const readline = require('readline');
const multer = require('multer');
const upload = multer();
const readFileAsync = promisify(fs.readFile);
const writeFileAsync = promisify(fs.writeFile);

const processingData = [];
let sortingRequests = 0;

module.exports = async function (context, req) {
    context.res = {
        headers: {
            'Content-Type': 'application/json'
        },
    };


    if (req.method === 'POST') {
        if (req.query.action === 'sort') {
            try {
                const inputFile = await processFileUpload(req);

                const startTime = performance.now();
                let requestsCounter = 0;

                const fileContent = await readFileAsync(inputFile.path, 'utf8');
                const dateArray = fileContent.split('n');

                dateArray.sort((a, b) => {
                    requestsCounter++;
                    return new Date(b) - new Date(a);
                });

                const sortedDateArray = dateArray.join('n');

                const data = {
                    requests: requestsCounter,
                    processingTime: performance.now() - startTime,
                };

                processingData.push(data);
                sortingRequests += requestsCounter;

                const filePath = `${context.executionContext.functionDirectory}/uploads/result.txt`;

                await writeFileAsync(filePath, sortedDateArray, 'utf8');

                context.res = {
                    status: 200,
                    body: { message: 'File sorted and saved as result.txt', processingData },
                };
            } catch (error) {
                context.res = {
                    status: 500,
                    body: { error: 'Internal Server Error', details: error.message },
                };
            }
        }
    } else if (req.method === 'GET') {
    if (req.query.action === 'download') {
        // Handle file download
        try {
            const filePath = `${context.executionContext.functionDirectory}/uploads/result.txt`;
            context.res = {
                status: 200,
                body: fs.readFileSync(filePath, 'utf8'),
                headers: {
                    'Content-Type': 'text/plain',
                    'Content-Disposition': 'attachment; filename=result.txt',
                },
            };
            context.done();
        } catch (error) {
            context.res = {
                status: 500,
                body: { error: 'Error downloading file' },
            };
            context.done();
        }
    } else if (req.query.action === 'sortingInfo') {
    
        // Handle sorting information request
        try {
            const sortingInfo = {
                requests: sortingRequests,
                processingData: processingData,
            };
            context.res = {
                status: 200,
                body: sortingInfo,
            };
            context.done();
        } catch (error) {
            context.res = {
                status: 500,
                body: { error: 'Internal Server Error' },
            };
            context.done();
        }
    } else {
        // Handle other GET requests as needed
        try {
            const greetingMessage = 'Hello from Azure Function!';
            context.res = {
                status: 200,
                body: { message: greetingMessage },
            };
            context.done();
        } catch (error) {
            context.res = {
                status: 500,
                body: { error: 'Internal Server Error' },
            };
            context.done();
        }
    }

} else {
        context.res = {
            status: 405,
            body: { error: 'Method Not Allowed' },
        };
        context.done();
    }
};
async function processFileUpload(req) {
    return new Promise((resolve, reject) => {
        upload.single('inputFile')(req, {}, (err) => {
            if (err) {
                console.error('Error processing file upload:', err);
                reject(new Error('Error processing file upload'));
            } else {
                resolve(req.file);
            }
        });
    });
}

Whenever I try to send a POST or GET request to the url provided by the function I keep getting 500 (Internal Server Error).

I tried logging the error but it is always the same thing, and I can’t figure out where I’m getting the code wrong because both the client-side and the server-side runs perfectly when I run it locally but it fails when I run it as a function.
Does anyone have any suggestions in order to debug the code and adjust it and solve the problem?

How do I remove all occurrences of a particular text from an array of strings?

This code’s goal is to take a multi-line string input (from a single cell in Google Sheets) and break it into pieces to the point where math operations can be performed for a total run mileage figure as the end result.

Example multi-line string input:

"2.5mi warmup
100met sprint
200met slow
repeat 4x
2mi tempo
1mi slow
repeat 8x
1mi jog
200met walk
repeat 4x
5mi cooldown"

After filtering out the first and last lines and then performing a split function using /x/ as the regex, I have the following array:

//arraysplitrepeatblocks = 
[ '  n100met sprint n200met slow nrepeat 4',
  ' n2mi tempo n1mi slow nrepeat 8',
  ' n1mi jog n200met walk nrepeat 4',
  ' n ' ]

I am trying to clean up this data by removing any mentions of “n” from each string within the array. I tried the code below but it is not an accepted function (I’m assuming due to the object being an array instead of a string; perhaps some iteration is necessary).

let arraycleanedup = arraysplitrepeatblocks.replace(/s+\n/,"");

//Error given:
TypeError: arraysplitrepeatblocks.replace is not a function

Expected result:

[ ' 100met sprint 200met slow repeat 4',
  ' 2mi tempo 1mi slow repeat 8',
  ' 1mi jog 200met walk repeat 4',
  ' ' ]

Any advice would be appreciated. Also, is there a way to delete that final empty array element? If so, the expected result after that operation would be:

[ ' 100met sprint 200met slow repeat 4',
  ' 2mi tempo 1mi slow repeat 8',
  ' 1mi jog 200met walk repeat 4']

expressjs cookies aren’t showing up in client

I am using expressjs cookieParser to sign and make http only JWT cookies. I’m not getting any errors but the cookies aren’t showing up on my Vite project or when I use Thunderclient to login then test a private route. It says req.cookies are ‘[Object: null prototype] {}’

              const AccessToken = generateAccessToken({
                username: user.username,
                email: user.email,
                id: user.id,
              });

              const RefreshToken = generateRefreshToken({
                username: user.username,
                email: user.email,
                id: user.id,
              });

              res
                .cookie("access_token", AccessToken, {
                  httpOnly: true,
                  secure: false,
                  sameSite: "none",
                  maxAge: 900000, // 15 min in milliseconds
                })
                .cookie("refresh_token", RefreshToken, {
                  httpOnly: true,
                  secure: false,
                  sameSite: "none",
                  maxAge: 86400000, // 1 day in milliseconds
                })
                .status(200)
                .json({
                  message: "Success login",
                  id: user.id,
                  email: user.email,
                  username: user.username,
                });

ngbTooltip – Cancel tooltip appearance during delay

I use ngbTooltip on many elements in my application.

Each tooltip is initialized as follows directly in the HTML code

  <div
    ngbTooltip="my tooltip"
    container="body"
    placement="left"
    openDelay="1000"
    triggers="hover"
    (click)="doSomething()"
  >
    click me !
  </div>

Everything works fine, unless the user clicks on the HTML element before the specified delay has elapsed.

In this case, the GUI is partially modified and the element used to trigger the tooltip is no longer displayed but after the delay, the tooltip is still displayed in the top left corner of the screen.

How to cancel the appearance of the tooltip once the button has been clicked or when the triggering element is no longer displayed ?

My versions are :
ng-bootstrap:16.0.0 and angular: 17.1.0

Match one or more specific pattern which is optional to repeat

Looking for a regex that could work in both Javascript and Java.

The whole String should match as long as each capital alphabet follows by a :Y.

All following examples should match in full.

So Any Capital letter followed by a :Y. Like A:Y.
If there is more than 1 pair it is separated by a comma.

S:Y,P:Y,T:Y,A:Y
S:Y,P:Y,T:Y,A:Y,C:Y
S:Y,P:Y,T:Y,A:Y,C:Y,:D:Y
A:Y
B:Y
D:Y,F:Y

All the following should never match. Cos 1 or more of them has :N.

S:Y,P:N,T:Y,A:Y
S:Y,P:Y,T:Y,A:Y,C:N
S:Y,P:Y,T:N,A:Y,C:N,:D:Y
A:N
B:N
D:Y,F:N

I don’t want to match in negative, like :N doesn’t exist.

^(?!.*:N).+$

Looking for a way to match :Y instead.

Tried the following but this ends up with multiple mini matches which is not what I am looking for.

[SPTA:Y,]+

This could work. But again, this has multiple mini matches.

(?:[A-Z]:Y(?:,|$))+

Could I get some help with this pls.

Maintaining background image aspect ratio when resizing canvas in Fabric.JS

So i have this canvas made in Fabric.JS and I need it to be as large or smaller that 600×600, so i set up the canvas, make its width and height the same as the image and then set maxWidth and maxHeight to 600. The intended behavior would be for the canvas to have a maximum width and maintaining the aspect ratio of the image, scaling it down. But it just stretches the image to fill the 600×600 space. Any suggestions?

I already tried using scaleImageToWidth() and scaleImageToHeight(), but it doesn’t work.
Here is my code:

var canvas = new fabric.Canvas('canvas');

fabric.Image.fromURL(path, function (oImg) {

    // sets the background image
    let img = new Image();
    img.src = path;

    img.onload = function () {

        canvas.setDimensions({
            width: this.width,
            height: this.height,
            maxWidth: 600,
            maxHeight: 600
        });
    }

    canvas.setBackgroundImage(oImg, canvas.renderAll.bind(canvas));
}

And here is the result:
result image

HTML Date Input not showing date using javascript

I am working on hybrid application using Angularjs and Angular 8. I am using datepicker to show date which is fetched from api but the problem the problem is if I use input type as “text” then it shows the date but if I use input type as “date” then it shows only dd/mm/yyyy. I have tried everything but all in vain. Any suggestion would be highly appreciated.

code

date is visible when input type is “text”

                        <div class="datepicker-wrap input-group">
                            <input uib-datepicker type="text" class="form-control"
                                   id="date_dead_line"
                                   placeholder="dd MM YYYY"
                                   value="{{(glPlmAsmt.data.deadline_time*1000) | date : 'dd MMM yyyy'}}"
                                   is-open = 'false'
                            >
                            <button type="button" class="btn gl-datepicker-btn"
                                    ng-click="glPlmAsmt.openDeadLineDate()">
                                <i class="glicon-date"></i>
                            </button>
                        </div>
                    </div>

date is not visible when input type is “date”

                    <div class="datepicker-cont-wrap">
                        <div class="datepicker-wrap input-group">
                            <input uib-datepicker type="date" class="form-control"
                                   id="date_dead_line"
                                   placeholder="dd MM YYYY"
                                   value="{{(glPlmAsmt.data.deadline_time*1000) | date : 'dd MMM yyyy'}}"
                                   is-open = 'false'
                            >
                            <button type="button" class="btn gl-datepicker-btn"
                                    ng-click="glPlmAsmt.openDeadLineDate()">
                                <i class="glicon-date"></i>
                            </button>
                        </div>
                    </div>

date is displayed

i need to display the date in dd MMM yyyy format but instead of date value it is showing only dd/mm/yyyy

date does not get displayed