Differences between HTML injection methods?

Is there a difference between html element injection methods? In terms of efficiency, ease of use, security…?

Usually, when I inject html, I do something like this:

const myDivInnerHtml = '<div><div>All the elements and etc...</div></div>';
const myDiv = document.createElement('div');
myDiv.id = "myDiv";
myDiv.innerHTML = myDivInnerHtml;
$('.document_element').append(myDiv);

Though I have at times done it more directly, like so:

const myDivInnerHtml = '<div id="myDiv"><div><div>All the elements and etc...</div></div></div>';
$('.document_element').append(myDivInnerHtml);

This is a simple process and nets me the results I need, but it can make it hard/annoying to navigate the code if myDivInnerHtml has a lot of elements (like when making a UI for a script, needing different tabs, buttons, and the like).

Why do I get a property assignment error while using script tags on HTML

I am practicing fetching API data and displaying it on a web page. I am using Go to fetch quotes data from an API service. I want an additional slideshow functionality for the web page that should display another fetched quote after 5 seconds using JavaScript.

However, only one quote is displayed on the web page, and no error is logged on the browser’s console. The only error my text editor displays is on the HTML file from the snippet below.

<script>
var quotes = {{.QuotesJSON}};
</script>

The following errors are being displayed:

  • Property assignment expected.javascript
  • Property destructuring pattern expected.javascript
  • Declaration or statement expected.javascript

I have tried declaring a field QuotesJSON in the data struct which is of type template.JS to indicate that the string being passed in should be treated as JavaScript code, allowing it to be safely embedded in HTML without being escaped using Go.

data := struct {
QuotesJSON template.JS
}{
QuotesJSON: template.JS(quotesJSON),
}

Where could the issue lie?

CSS/JS pagination where the number of pages is automatically discovered from a specific folder on the server

I’m quite new to CSS (and unfortunately ignorant of JS) and would like to know if this is possible:

I would like to code script for CSS (or JS/jQuery if someone could help me with it) for the following situation: I have a website where there is a top-level archive page (a table of contents) with links to individual archive pages, and the actual archive pages are in a folder below that on the server. On the individual archive pages, I would like to be able to load a script (currently I’m using an iframe to load a second nav page into the text page) with the navbar for the archives in it, which consists of prev, TOC, and next button images. Here’s where it’s a bit tricky: I want the pagination to update the prev/next buttons depending on the current filename of the page (it ends in a number, for example (filename) 1001-1014, but then skips to a second set of numbers at the end of the current “chapter,” for example (filename) 2001-2022 etc.), so that it always sends the user to the file previous/next in the row, and so that when the user reaches the beginning of the set, the prev button disappears, and when it reaches the end of all sets, the next button disappears.

Ideally, the coding would be able to find how many pages were in the archive folder itself (and how many were in the (filename) 1001 set, how many in the (filename) 2001 set, etc.), and paginate accordingly, but it would also be fine to have to update the min/max number of pages manually somewhere if that isn’t possible.

So… IS it possible to do this with CSS? If not, can someone help me with the javascript (assuming it’s even possible with that)? I looked through the answers on this website and found this (https://github.com/gbirke/jquery_pagination), but I’m afraid it might as well be in a foreign language to me. Which I suppose it is.

I do have a friend more versed in CSS/JS who helped me with the following code, but it seems not to work properly if you don’t go directly from the ToC to page 1001, and page up from there. He says my plan isn’t possible without knowing more JS, at the very least, and possibly not at all, due to some restriction about not being able to number the pages in the archive folder. (The archive ToC is in the same uppermost folder as the index.html page.)

script:

let maxpages = 1014;

if (sessionStorage.getItem("archivenum") < 1001)
   {
   sessionStorage.setItem("archivenum", 1001);
   }


function navUp() {
   window.open('../CC weblog.html', '_parent');
}

function navPrev() {
   let archivenext = sessionStorage.getItem("archivenum");
   if (archivenext > 1001) {
      archivenext--;
      butVis();
      sessionStorage.setItem("archivenum", archivenext);
   }
    var prevfile = "../CC logs/CC log " + archivenext + ".html";
    window.open(prevfile, "_parent");
}

function navNext() {
   let archivenext = sessionStorage.getItem("archivenum");
   if (archivenext < maxpages) {
      archivenext++;
      butVis();
      sessionStorage.setItem("archivenum", archivenext);
    }    
    var nextfile = "../CC logs/CC log " + archivenext + ".html";
    window.open(nextfile, "_parent");
}  
  
function butVis() {
   let archivenext = sessionStorage.getItem("archivenum");
   if (archivenext == 1001) {
      butPrev.setAttribute('style', 'Visibility: hidden');
   }
   else {
      butPrev.setAttribute('style', 'Visibility: visible');
   }

   if (archivenext == maxpages) {
      butNext.setAttribute('style', 'Visibility: hidden');
   } 
   else {
      butNext.setAttribute('style', 'Visibility: visible');
   }
}

window.onload = function() {
   butVis();
}

script on each HTML page:

document.addEventListener('DOMContentLoaded', ()=>{
    let nBody = document.querySelector('body')
    let nIframe = document.createElement('iframe');
    nIframe.setAttribute('id', "show-iframe");
    nIframe.style.display = 'none';
    nIframe.style.position = 'absolute';
    nBody.appendChild(nIframe);
  });

script on the archive navbar page:

<div class="nav">
    <div class="nav flex">
<img class="nav" src="../CC images/buts/but-back.png" alt="prev" onclick="navPrev()" name="butPrev">

<img class="navArch" src="../CC images/buts/but-up.png" alt="TOC" onclick="navUp(); sessionStorage.clear()">

    <img class="nav" src="../CC images/buts/but-for.png" alt="next" onclick="navNext()" name="butNext">
    </div>
</div>

Any help is MUCH appreciated!

How to make a dynamic og:image with JS to share properly in Facebook and X/Twitter?

I cannot get this to work. When I try to share an WordPress-article in X, Telegram and Facebook, it shows the wrong image and the wrong title.

I know it has to with my setup in html, with a static og:image etc.

I would like my JS to solve this, so it fetches the correct image, title etc.

But how do I do that? Does any body has some good JS-code for this?

I use WEPB-images in the articles, if that could be the problem.

PS. I do not want to use WordPress-plugins.

Everytime I try to share articles with a social button.

Writing Files in a JSON without using require(‘fs’)

I have written a code where it coverts that I should be writting in a file (JSON) and gets read after in my node app. The problem is, if it gets uploaded in the web, this problem appears:

fs.writeFileSync("./newgenesis-sql-db/itemDatabase.json", o, (function(a) {
            a ? console.log("Error writing file", a) : console.log("Successfully wrote file")
        }
rmmz_managers.js:2036 ReferenceError: fs is not defined

Meaning it does not require the fs which is of course done via require(‘fs’). I have a hunch that this is because require.js is not uploaded, but even so, since it is via node, I opted to believe it should work. Do we have to attach it?

This is my code:

    const jsonString = JSON.stringify(actorFiles)
    fs.writeFileSync('./newgenesis-sql-db/actorDatabase.json', jsonString, err => {
        if (err) {
            console.log('Error writing file', err)
        } else {
            console.log('Successfully wrote file')
        }
    })
    const jsonString2 = JSON.stringify(playerItems)
    fs.writeFileSync('./newgenesis-sql-db/itemDatabase.json', jsonString2, err => {
        if (err) {
            console.log('Error writing file', err)
        } else {
            console.log('Successfully wrote file')
        }
    })

The intention was just to actually write the strings I placed inside the JSON. How can I make sure that it will be written on the JSON when the game gets uploaded online? Is there a way to write the texts I want in the JSON without using require(‘fs’) and if so, how?

videos and images sent are not being saved in my Electron + React.js build

When I use npm start and run the app normally, I can add and view all images and videos without any issues. However, when I build the app, everything else gets saved correctly, but the images fail to load. Apart from loading images or videos, everything else works fine. When I check the database in local files, the image field appears empty. By the way, I’m using a local database (db-local).

Additionally, if you notice any potential issues beyond what I’ve mentioned, I’d appreciate it if you could point them out. I’m primarily a back-end developer, and this is my first front-end and Electron project.

react.js part

import React from 'react'
import Typography from '@mui/material/Typography';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import Paper from '@mui/material/Paper';
import Chip from '@mui/material/Chip';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import InputAdornment from '@mui/material/InputAdornment';
import { useDispatch } from 'react-redux';
import { startloading } from '../store/slices/userSlice';
import { Controller, useForm } from 'react-hook-form';
import AddIcon from '@mui/icons-material/AddRounded';
import IconButton from '@mui/material/IconButton';
import Attachment from '@mui/icons-material/AttachmentRounded';
import MediaPreview from '../components/MediaPreview';
import { Container, Switch } from '@mui/material';
import { useNavigate } from 'react-router-dom';
import ArrowBackIos from '@mui/icons-material/ArrowBackIosRounded';
const AddRule = () => {
    const [type, setType] = React.useState('');
    const [newRule, setNewRule] = React.useState('');
    const [controlledRules, setControlledRules] = React.useState([]);
    const [preview, setPreview] = React.useState(null);
    const [previewOpen, setPreviewOpen] = React.useState(true);
    const [error, setError] = React.useState(null);
    const ruleInputRef = React.useRef(null);
    const dispatch = useDispatch();

    const {
        control,
        handleSubmit,
        getValues,
        reset,
        setValue,
        formState: { errors },
    } = useForm({
        values: React.useMemo(() => ({
            rules: [],
            rule_title: "",
            rule_timeout_unit: "seconds",
            rule_timeout: 1,
            rule_delay: 1,
            rule_response: "",
            image: ""
        }), [])
    })

    const addRuleHandler = (rule) => {
        if (rule.trim() === '') return setError(prevError => ({ ...prevError, rules: "Kural boş bırakılamaz." }));
        if (controlledRules.includes(rule)) return setError(prevError => ({ ...prevError, rules: "Her kural bir kere girilmelidir." }))
        setControlledRules([...controlledRules, rule])
        setError(prevError => ({ ...prevError, rules: "" }))
        setNewRule('');
    }

    React.useEffect(() => {
        setValue("rules", controlledRules);
    }, [controlledRules, setValue]);

    const deleteRuleHandler = (rule) => {
        setControlledRules(controlledRules.filter(r => r !== rule))
    }

    const handleFileChange = (file, field) => {
        if (file && (file.type === "video/mp4" || file.type === "image/png" || file.type === "image/jpeg")) {
            const maxSize = 15 * 1024 * 1024;
            if (file.size > maxSize) {
                return setError(prevError => ({ ...prevError, file: "Medya boyutu 15MB'dan büyük olamaz." }));
            }

            const reader = new FileReader();

            reader.onloadend = () => {
                const base64 = reader.result.split(",")[1];
                field.onChange(base64);
                setValue("image", base64)
            };

            reader.readAsDataURL(file);
            setType(file.type);
            setPreview({ url: URL.createObjectURL(file), type: file.type });
            setError(null);
        } else {
            setError(prevError => ({ ...prevError, file: "Sadece .png, .jpg veya .mp4 dosyaları yüklenebilir." }));
            field.onChange("");
            setPreview(null);
        }
    };

    const onSubmit = data => {
        if (controlledRules.length == 0) return setError(prevError => ({ ...prevError, rules: "Kural boş bırakılamaz." }))
        dispatch({
            type: 'websocket/sendMessage', payload: {
                data_type: 'add_rule', formdata: { ...data, type }
            }
        });
        dispatch(startloading());
        dispatch({ type: 'websocket/sendMessage', payload: { data_type: 'get_rules' } });
        setControlledRules([]);
        setPreview(null);
        fileInputRef.current.value = "";
        reset()
    };

    const fileInputRef = React.useRef(null);

    const handleFileDelete = () => {
        setError(null);
        setPreview(null);
        setValue("image", "");
        if (fileInputRef.current) {
            fileInputRef.current.value = "";
        }
        setType("");
    }

    const navigate = useNavigate();

    return (
        <Container>
            <form onSubmit={handleSubmit(onSubmit)}>
                <Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <IconButton onClick={() => navigate('/')}>
                        <ArrowBackIos />
                    </IconButton>
                    <Typography sx={{ fontWeight: '400', margin: '40px 0', fontSize: '32px', textAlign: 'center' }} variant='h5'>Kural Ekleyin</Typography>
                    <Box />
                </Box>
                <Controller name="rule_title"
                    control={control}
                    rules={{
                        required: "Kural başlığı gereklidir",
                        minLength: { value: 3, message: "Başlık en az 3 karakter olmalı" },
                        maxLength: { value: 25, message: "Başlık en fazla 25 karakter olabilir" },
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            {...field}
                            sx={{ width: "100%" }}
                            type="text"
                            label="Kural başlığı"
                            placeholder="Kural başlığı girin."
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Paper sx={{ padding: "10px", marginTop: '10px' }}>
                    <Typography sx={{ fontSize: '16px', fontWeight: '400', display: 'block', textAlign: 'center' }} variant='h6'>Cevap Verme Kuralları</Typography>
                    <Box sx={{ display: 'flex', gap: '5px', flexWrap: 'wrap', padding: "10px", marginTop: '5px' }}>
                        {controlledRules.map((subRule, subIndex) =>
                            <Chip onDelete={() => deleteRuleHandler(subRule)} size='small' key={subIndex} label={subRule} />
                        )}
                    </Box>
                    <TextField
                        size='small'
                        value={newRule}
                        sx={{ width: "100%", marginTop: '15px' }}
                        label="Yeni Kural"
                        onKeyDown={e => {
                            if (e.key === 'Enter') {
                                e.preventDefault();
                                addRuleHandler(newRule);
                            }
                        }}
                        placeholder='Kural girin.'
                        ref={ruleInputRef}
                        onChange={e => setNewRule(e.target.value)}
                        slotProps={{
                            input: {
                                endAdornment: (
                                    <InputAdornment position="end">
                                        <IconButton type='button' onClick={() => addRuleHandler(newRule)}>
                                            <AddIcon />
                                        </IconButton>
                                    </InputAdornment>
                                )
                            }
                        }}
                        error={!!error?.rules}
                        helperText={!!error?.rules ? error.rules : ''}
                    />
                </Paper>

                <Box sx={{ display: 'flex', alignItems: 'flex-start', gap: '5px' }}>
                    <Controller name="rule_timeout"
                        control={control}
                        rules={{
                            min: { value: 1, message: "1 veya daha yüksek bir sayı seçiniz." },
                            max: {
                                value: getValues().rule_timeout_unit === "seconds" || getValues().rule_timeout_unit === "minutes" ? 59
                                    : getValues().rule_timeout_unit === "hours"
                                        ? 23
                                        : 1, message: "Saniye veya Dakika seçili ise en fazla 59, saat seçili ise en fazla 23, güne seçili ise en fazla 1 olmalıdır."
                            },
                        }}
                        render={({ field, fieldState }) => (
                            <TextField
                                {...field}
                                sx={{ width: '100%', marginTop: '20px', }}
                                type="number"
                                label='Tekrar kullanım aralığı'
                                placeholder='Tekrar kullanım aralığını girin.'
                                variant="outlined"
                                error={!!fieldState.error}
                                helperText={!!fieldState.error ? fieldState.error?.message : ''}
                            />
                        )}
                    />
                    <Controller name="rule_timeout_unit"
                        control={control}
                        render={({ field }) => (
                            <Select defaultValue={"seconds"} sx={{ flex: "1", marginTop: '20px' }} {...field} fullWidth>
                                <MenuItem value="seconds">Saniye</MenuItem>
                                <MenuItem value="minutes">Dakika</MenuItem>
                                <MenuItem value="hours">Saat</MenuItem>
                                <MenuItem value="day">Gün</MenuItem>
                                <MenuItem value="onetime">Tek Seferlik</MenuItem>
                            </Select>
                        )}
                    />
                </Box>
                <Controller name="rule_delay"
                    control={control}
                    rules={{
                        min: { value: 1, message: "Cevap gecikmesi en az 1 saniye olabilir." },
                        max: { value: 59, message: "Cevap gecikmesi en fazla 59 saniye olabilir." }
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            {...field}
                            sx={{ width: '100%', marginTop: '20px', }}
                            type="number"
                            label='Cevap gecikmesi (Saniye)'
                            placeholder='Cevap gecikmesini girin. (Saniye)'
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Box sx={{ display: 'flex', alignItems: 'center' }}>
                    <Controller name="image"
                        control={control}
                        render={({ field }) => (
                            <Box sx={{ marginTop: '10px' }}>
                                <>
                                    <label htmlFor="file-upload1">
                                        <Button disabled={getValues().image ? true : false} startIcon={<Attachment />} variant="text" component="span">
                                            Bot cevabına bir medya ekleyin.
                                        </Button>
                                    </label>
                                    <input
                                        disabled={getValues().image ? true : false}
                                        id="file-upload1"
                                        accept=".mp4,.jpg,.png"
                                        multiple={false}
                                        type="file"
                                        ref={fileInputRef}
                                        hidden
                                        onChange={(e) => {
                                            const file = e.target.files[0];
                                            handleFileChange(file, field);
                                        }}
                                    />
                                </>
                            </Box>
                        )}
                    />
                    {preview &&
                        <div style={{ marginTop: '5px' }}>
                            <Switch checked={previewOpen} size='small' onChange={() => setPreviewOpen(!!!previewOpen)} />
                            <Typography variant='body2' component={'span'}>Medyayı Önizle</Typography>
                        </div>
                    }
                </Box>
                {error?.file && <Typography color='error' variant='caption'>{error.file}</Typography>}
                {(preview && previewOpen) &&
                    <MediaPreview setRemove={handleFileDelete} media={preview} />
                }

                <Controller
                    name="rule_response"
                    control={control}
                    rules={{
                        required: { value: true, message: "Bot cevabı gereklidir." },
                        minLength: { value: 3, message: "Bot cevabı en az 3 karakter olabilir." },
                        maxLength: { value: 64000, message: "Bot cevabı en fazla 64.000 karakter olabilir." }
                    }}
                    render={({ field, fieldState }) => (
                        <TextField
                            multiline
                            rows={10}
                            {...field}
                            sx={{ width: '100%', marginTop: '20px', }}
                            type="number"
                            label='Bot cevabı'
                            placeholder='Bot cevabını girin.'
                            variant="outlined"
                            error={!!fieldState.error}
                            helperText={!!fieldState.error ? fieldState.error?.message : ''}
                        />
                    )}
                />
                <Button sx={{ marginTop: '20px' }} size='large' variant='contained' color='success' type='submit'>Kaydet</Button>
                <Button onClick={() => { reset(); setPreview(null); setControlledRules([]); }} sx={{ marginTop: '20px', marginLeft: '5px' }} size='large' color='warning' variant='contained'>Sıfırla</Button>
            </form>
        </Container>
    )
}

export default AddRule

This is electron.js ws part

case "add_rule": {
                object.formdata.rule_delay = parseInt(object.formdata.rule_delay)
                object.formdata.rule_timeout = parseInt(object.formdata.rule_timeout)

                const item = await command.create({ ...object.formdata, image: '' }).save();

                if (object.formdata.image) {
                    const buffer = Buffer.from(object.formdata.image, 'base64');
                    const filePath = path.join(__dirname, 'images', `${item._id + '_' + Date.now()}.${object.formdata.type.split('/')[1]}`);
                    await fs.promises.writeFile(filePath, buffer);
                    const outputFile = 'images/temp_output.mp4';

                    if (object.formdata.type.startsWith('video/')) {
                        ffmpeg(filePath)
                            .videoCodec('libx264')
                            .audioCodec('aac')
                            .audioBitrate(128)
                            .outputOptions('-crf', '23')
                            .outputOptions('-preset', 'fast')
                            .on('start', (commandLine) => {
                                console.log('FFmpeg komutu başladı:', commandLine);
                            })
                            .on('progress', (progress) => {
                                console.log(`İlerleme: ${progress.percent.toFixed(2)}% tamamlandı.`);
                            })
                            .on('end', () => {
                                console.log('FFmpeg işlemi tamamlandı, dosya değiştiriliyor...');
                                fs.unlink(filePath, (err) => {
                                    if (err) {
                                        console.error('Eski dosya silinirken hata oluştu:', err.message);
                                    } else {
                                        fs.rename(outputFile, filePath, (err) => {
                                            if (err) {
                                                console.error('Yeni dosya taşınırken hata oluştu:', err.message);
                                            } else {
                                                console.log('Dosya başarıyla güncellendi!');
                                            }
                                        });
                                    }
                                });
                            })
                            .on('error', (err) => {
                                console.error('Hata oluştu:', err.message);
                                if (fs.existsSync(outputFile)) {
                                    fs.unlink(outputFile, () => {
                                        console.log('Geçici dosya silindi.');
                                    });
                                }
                            })
                            .save(outputFile);
                    }
                    object.formdata.image = filePath;
                    let komut = await command.findOne({ _id: item._id });
                    komut.image = filePath;
                    komut.save();
                }
                wss.clients.forEach((wsClient) =>
                    wsClient.send(JSON.stringify({ data_type: 'rule_added', message: 'Kural başarıyla eklendi.', status: true }))
                )
                break;
            }

Javascript TABS with KEYDOWN Function

I am trying to Simplify this code. Here is what i have so far.

<style type="text/css">
    body {
        background-color: #6A6A6A;
        overflow: hidden;
    }

    .box {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
    }

    .tabcontent1 {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        display: none;
    }

    #image1 {
        background-color: bisque;
    }

    #image2 {
        background-color: #76552d;
    }

    #image3 {
        background-color: #432b0d;
    }
</style>
<div class="box">
    <div id="image1" class="tabcontent1"></div>
    <div id="image2" class="tabcontent1"></div>
    <div id="image3" class="tabcontent1"></div>
</div>
<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
<script>
    function openCity1(evt, cityName) {
        var i, tabcontent1;
        tabcontent1 = document.getElementsByClassName("tabcontent1");

        for (i = 0; i < tabcontent1.length; i++) {
            tabcontent1[i].style.display = "none";
        }
        document.getElementById(cityName).style.display = "block";
        evt.currentTarget.className += " active";
    }

    var clicked = 0;
    $("body").on("keydown", function (event) {
        if (event.which == 38 && clicked == 0) {
            openCity1(event, 'image1');
            clicked = 1;
        }
        else if (event.which == 38 && clicked == 1) {
            openCity1(event, 'image2');
            clicked = 2;
        }
        else if (event.which == 38 && clicked == 2) {
            openCity1(event, 'image3');
            clicked = 3;
        }

        else if (event.which == 40 && clicked == 3) {
            openCity1(event, 'image2');
            clicked = 2;
        }
        else if (event.which == 40 && clicked == 2) {
            openCity1(event, 'image1');
            clicked = 1;
        }
    });
</script>

I want to change TABS with the UP and DOWN arrows.
I want it to be as small as possible.
So basically i want to change TABS with the keyboard but not the Clicked = 1 way ..Or Maybe the Clicked++ way .
I also tried the Jquery tabs way but could not figure that out.

How to finish the input box editing with enter key or focus out

I have input box like this,

I want to finish editing by pushing enter key or blur the input .

<input 
  ref={titleEditBox} type="text" onBlur={blurEditBox} 
  onKeyDown={keyDownFinishEdit}></input>

const blurEditBox = () =>{
    finishEditbox();
}
const keyDownFinishEdit = (e) =>{
  if (e.keyCode == 13){
     finishEditText();
  }
  e.stopPropagation();
}

However when i push the return key it calles the keyDownFinishEdit and then onBlur so finishEditText() is called twice.

So my idea is calling , unfocus from keyDownFinishEdit.

Is it possible or is there any good idea to sort out this?

Changing selected value in dropdowns dynamically, but the dropdowns are also dynamically populated based on previous selections

I want to change the selected values of the dropdowns dynamically with the updateDropdowns() function that i created. Almost all of the dropdowns are dynamically populated based on previous selections.

The problem is only those dropdowns that dont rely on previous selection have their values changed.

this is my updateDropdowns() function:

function updateDropdowns(details) {
        const startT = details.startTime.substring(0, 5);
        const endT = details.endTime.substring(0, 5);

        $('#courses').val(details.courseCode).change();
        console.log('Course set:', details.courseCode);
    
        $('#subjects').val(details.subjectCode).change();
        console.log('Subject set:', details.subjectCode);
    
        $('#sections').val(details.sectionCode).change();
        console.log('Section set:', details.sectionCode);
    
        $('#rooms').val(details.roomID).change();
        console.log('Room set:', details.roomID);
    
        $('#days').val(details.dayOfWeek).change();
        console.log('Day set:', details.dayOfWeek);
    
        $('#teachers').val(details.idNumber).change();
        console.log('Teacher set:', details.idNumber);
    
        $('#startTime').val(startT).change();
        console.log('Start time set:', startT);
    
        $('#endTime').val(endT).change();
        console.log('End time set:', endT);
    }

I also tried putting delays but it only made it not display anything at all.

function updateDropdowns(details) {
    
    const startT = details.startTime.substring(0, 5);
    const endT = details.endTime.substring(0, 5);

    setTimeout(() => {
        $('#courses').val(details.courseCode).change();
        console.log('Course set:', details.courseCode);
    }, 300);

    setTimeout(() => {
        $('#subjects').val(details.subjectCode).change();
        console.log('Subject set:', details.subjectCode);
    }, 600);

    setTimeout(() => {
        $('#sections').val(details.sectionCode).change();
        console.log('Section set:', details.sectionCode);
    }, 900);

    setTimeout(() => {
        $('#rooms').val(details.roomID).change();
        console.log('Room set:', details.roomID);
    }, 1200);

    setTimeout(() => {
        $('#days').val(details.dayOfWeek).change();
        console.log('Day set:', details.dayOfWeek);
    }, 1500);

    setTimeout(() => {
        $('#teachers').val(details.idNumber).change();
        console.log('Teacher set:', details.idNumber);
    }, 1800);

    setTimeout(() => {
        $('#startTime').val(startT).change();
        console.log('Start time set:', startT);
    }, 2100);

    setTimeout(() => {
        $('#endTime').val(endT).change();
        console.log('End time set:', endT);
    }, 2400);
}

Not Able to Remove Item From Comma Separated Cookie Value

I have cookie stored like 2,55,33,21,12 which each number is SKU of a product stored in wish cookie now if user remove wish product I am removing it from the cookie for example if user want to remove SKU 33 the cookie will change to 2,55,21,12. this process should be continued until the last product SKU removed from the cookie then will delete the cookie when the last SKU is removed. I am using this code

     remove: function (name, valueToRemove, options) {
                options = options || {};
    
                // Get the cookie value and ensure it's a string
                const rawValue = this.get(name) || "";
                const existingValues = typeof rawValue === "string" ?
                    rawValue.split(",").filter((val) => val !== valueToRemove) : []; // Handle cases where get() doesn't return a string
    
                if (existingValues.length > 0) {
                    // If there are remaining values, update the cookie
                    this.set(name, existingValues.join(","), options);
                } else {
                    // If no values remain, delete the cookie
                    this.delete(name, options); // Ensure delete method exists and works as intended
                }
            }

but this deletes entire cookie at first request like $.cookie.remove("wishCookie", "33", { expires: 7, path: "/" });

JavaScript promisses and closures

The following code creates a dummy promise and executes it inside a function.

async function sleep(x) {
  return new Promise((resolve) => {
    setTimeout(resolve, x * 1000);
  });
}

class Run {
  async go(x) {
    console.log('sleep', x);
    await sleep(x);
    console.log('wait up', x);
  }
}

function runner() {
  const r = new Run();
  // Note no `await`
  r.go(1);
  r.go(2);
  r.go(3);

  // Note tha we are NOT returning `r` from this function.
}

async function main() {
  runner();
}

Promise.resolve().then(() => {
  return main();
});

The runner() function is not inside another function, not returning anything and not being returned to another caller. So we can assume (can we?) that there is no closure being formed here.

The output of the above script is this:

sleep 1
sleep 2
sleep 3
wait up 1
wait up 2
wait up 3

The promise created inside the runner function seems to outlive function’s life. This seems odd. Usually once the function returns, its local variables would be destroyed – but the promise lives on until resolved.

Is this “run to completion” semantics, or something else?

Proper flow for fetching large “editable” data in react

I am trying to identify what would be the proper way to handle the kind of problem we face as react devs when dealing with “proper way” of fetching/managing editable data. Let me paint an exaggerated picture so that we have an idea on what is the problem.

Assumptions:

  1. no server side rendering – developmental constraint of the project
  2. datasets are 200+ MB large JSON files with many fields
  3. Redux is used as an external stor
  4. data is not “global” or “app” level (what I mean by this is, the data is only used by a SINGLE component – the editor – and no other component actually needs data access) There can be multiple instances of the editor open though.

So here are the problems im having with identifying what is the proper pattern here:

  1. When to data fetch?
  2. Where to “store” the fetched data

Lets start with an easier (more common) one

When to data fetch

The primary concern here is that the data needs to be available for rendering inside an “editor” which could be loaded on a page, thus we have the case of “you need data to show the page”, which means that you need to handle data fetching (in case no data is present) on page reload (refresh).

But we cant use the useEffect to load this data, that is an anti-pattern.
And data being present is not a result of a user “clicking” some handler.

The obvious answer would be, preload the data with SSR for the case of “refresh” / “initial” page load – which cannot be done due to constraints. So how to resolve this ?
Additionally, this still leaves the issue of user loading up on a different page and navigating to this page. Obviously we do not want to couple the <link> navigation to datafetching, which leaves me kinda stumped as to what is the pattern.

I just do not see a way to decouple “navigation” and data fetching without the use of useEffect to fetch the data.

Where to store the data

Now this one is bit more…. complicated.
The “editor” should be compared to a form of sorts. It has its own model which it works with and updates and it does not interact with an external storage for this purpose. It can “preload” / “load” the data, but once loaded, it uses its own state to work with any changes that may be done by the user. In other words, the EDITOR is where the data is ultimately stored. However….

Editor cannot “fetch” the data, so something else has to “pass” data into it. This can be done through a preload property on initial render or through the use of ref.current.load method afterwards. Both of these come with their own problems.

Preload

For this to work, it must be passed as a prop during the initial rendering of the Editor, this means that the data must already be loaded when this happens or in other words:

const Page = () => {
  const [data, setData] = useState()


  useEffect(()=>{
    fetchData().then(setData)
  }, [])


  if(!data) return null // or some loader...

  return <Editor preload={data}/>
}

But this leads to “duplicated” data being stored, one in Page state, one inside the editor. Same thing is the case for external storage, such as Redux. Alternatively, one could use the editor’s ref to “load” the state as such:

Loading after render
const Page = () => {
  const ref = useRef()


  useEffect(()=>{
    fetchData().then(ref.current.load)
  }, [])

  return <Editor ref={ref}/>
}

This way we skip the local state, however we have to “render” the editor for us to access the ref and since we are downloading 200MB we will have a blank editor with no data for a while, alongside a slew of other issues with conciling loaded data and whatever happened within the editor. Some loader within the editor itself could prevent this, but editor is an abstraction that is unaware of “loading” and could also be “opened” with no data in case you are “creating” rather than “editing” a data-set. Obviously this aint a solution either.

What would be the best approach to solve these two issues.

Is it worth making a web server in c++ in 2024? [closed]

As a student in my junior year, Is it worth making a web server in c++? I am curious how things work in c++, should I invest my time in it? is this even worth in 2024?

As a passionate C++ enthusiast, I created my first web application using Node, Express, and MySQL. However, I became curious about using C++ as a backend instead of JavaScript. After doing some research, I discovered that to use C++ as a backend, you need to build a web server from scratch, which can then serve as the backend for your application.