Is passing a JSON between Javascript and Flask a secure way to convert a JSON to a CSV in flask?

On my flask app I want to create a feature so a user can query the database, have the browser display the results in a table and then download it in a csv.

Is the plan I have below secure? Would end users be able to manipulate the JSON?

My overall design plan to accomplish this is as follows in pseudocode:

  • (Python) pulls Query from database and puts results in JSON using JSONIFY

  • (Python) returns JSON to Javascript file

  • (Javascript) Displays the JSON in an HTML table

  • (Javascript) User clicks button and Javascript sends JSON to flask endpoint

  • (Python) Flask endpoint converts JSON into CSV

React-Native-fs wont open my uri from document-picker

I pick a file via DocumentPicker, get the URI, and pass it to a function which should open my Document (csv). But i get the Error ENSCOCOAERRORDOMAIN260.
Also i tried to see if there’s an file -nope. But i just selected it via DocumentPicker (i get Filename, size, etc via it)

That would be the function:

 async readCSVsaveTOJson(uri){
    var RNFS = require('react-native-fs');

    //console.log(RNFS.TemporaryDirectoryPath);
    realDoc = uri.replace('file:/',  '');
    console.log(realDoc);
    var kacke = '';
    var counter = 0;
    for(var i in realDoc){
      if(counter > 0){
        kacke += realDoc[i];
      }
      counter++;
    }

    console.log('exists?');
    console.log(RNFS.exists(kacke));

    RNFS.readDir(kacke')
      .then((result) => {
        // stat the first file
        console.log('result');
        return Promise.all([RNFS.stat(result[0].path), result[0].path]);
      })
      .then((statResult) => {
        if (statResult[1].isFile()) {
          // if we have a file, read it
          var content = RNFS.readFile(kacke);
          console.log('--------------------------');
          console.log(content);
          return RNFS.readFile(statResult[1], 'utf8');
        }
    
        return 'no file';
      })
      .then((contents) => {
        // log the file contents
        console.log(contents);
      })
      .catch((err) => {
        console.log('ERROR, theres is nothing');
        console.log(err.message, err.code);
      });
  } 

it throws console.log('ERROR, theres is nothing');.. buut i know there should be something.

Any recommandings?
Huge Thanks

Why this alpine.js x-for looping 2 times

I use the alpine.js to render a modal with a x-for loop who populate a select. Strange behavior, the x-for seems looping 2 times and I can’t understand why:

the code:

<script>
    document.addEventListener('alpine:init', () => {
        Alpine.data('load', () => ({
            indicateurs: [],
            indicateurDictionnaireForm: {},
            typeIndicateurs: {},
            detectedTypeIndicateur: '',
            loadIndicateur() {
                $('#overlay').fadeIn();
                fetch('<%= request.getContextPath() %>/mesures.load.action')
                    .then(response => response.json())
                    .then(data => {
                        this.indicateurs = data;
                        $('#overlay').fadeOut();
                    })
                    .catch(error => {
                    });
            },
            deleteIndicateur(id) {
                $.ajax({
                    type: "DELETE",
                    url: "<%= request.getContextPath() %>/mesures.delete.action?indicateurDictionnaireId=" + id,
                }).then(() => this.loadIndicateur());
            },
            postForm() {
                return {
                    submitData() {
                        $.ajax({
                            type: "POST",
                            url: "<%= request.getContextPath() %>/mesures.save.action",
                            data: JSON.stringify(this.indicateurDictionnaireForm),
                            dataType: "JSON",
                            contentType: "application/json; charset=utf-8",
                        }).then(() => {
                            this.loadIndicateur();
                            this.resetForm();
                            $('#modalIndicateur').modal('hide');
                        })
                    },
                }
            },
            editIndicateur(id) {
                $.ajax({
                    type: "GET",
                    url: "<%= request.getContextPath() %>/mesures.load.type-indicateur.action"
                }).then(data => {
                    this.typeIndicateurs = data;
                }).then(
                    $.ajax({
                        type: "GET",
                        url: "<%= request.getContextPath() %>/mesures.edit.action?indicateurDictionnaireId=" + id,
                    }).then(data => {
                        this.indicateurDictionnaireForm = data;
                        this.detectedTypeIndicateur = data.typeIndicateur.code;
                        this.loadIndicateur();
                        $('#modalIndicateur').modal('show');
                    })
                );
            },
            resetForm() {
                this.indicateurDictionnaireForm = {};
            }
        }))
    })
</script>

the modal code:

<div class="modal" tabindex="-1" role="dialog" id="modalIndicateur">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title"><s:text name="indicateur.ce.add"/></h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form action="<%= request.getContextPath() %>/save.action"
                      method="POST"
                      class="w-64 mx-auto" x-data="postForm()" @submit.prevent="submitData">
                    <div class="form-group" style="padding-left: 15px; padding-bottom: 5px">
                        <div class="row">
                            <label class="control-label col-md-2" style="text-align: left"
                                   for="libelle_fr">
                                <s:text name="indicateur.ce.libelle_fr"/></label>
                            <div class="col-md-8">
                                <input id="libelle_fr" type="text"
                                       name="indicateurDictionnaireForm.libelleFr"
                                       class="form-control input-sm"
                                       x-model="indicateurDictionnaireForm.libelleFr">
                            </div>
                        </div>
                        <div class="row">
                            <label class="control-label col-md-2" style="text-align: left"
                                   for="libelle_nl">
                                <s:text
                                        name="indicateur.ce.libelle_nl"/></label>
                            <div class="col-md-8">
                                <input id="libelle_nl" type="text"
                                       name="indicateurDictionnaireForm.libelleNl"
                                       class="form-control input-sm"
                                       x-model="indicateurDictionnaireForm.libelleNl">
                            </div>
                        </div>
                        <div class="row">
                            <label class="control-label col-md-2" style="text-align: left"
                                   for="code">
                                <s:text name="indicateur.ce.code"/></label>
                            <div class="col-md-8">
                                <input id="code" type="text"
                                       name="indicateurDictionnaireForm.typeIndicateurCode"
                                       class="form-control input-sm"
                                       x-model="indicateurDictionnaireForm.code">
                            </div>
                        </div>
                        <div class="row">
                            <label class="control-label col-md-2" style="text-align: left"
                                   for="code">
                                <s:text name="indicateur.ce.code"/></label>
                            <div class="col-md-4">
                                <div class="flex flex-col w-full md:w-2/3">
                                    <select x-model="indicateurDictionnaireForm.typeIndicateurCode"
                                            class="form-control input-sm">
                                        <template x-for="option in typeIndicateurs" x-effect="console.log(detectedTypeIndicateur)">
                                            <option :key="option.code"
                                                    :value="option.code"
                                                    selected="option.code === detectedTypeIndicateur"
                                                    x-effect="console.log('code:', option.code, ' type: ', detectedTypeIndicateur)"
                                                    x-text="option.libellefr"></option>
                                        </template>
                                    </select>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal"
                                @click="resetForm()">
                            <s:text name="common.button.quitter"/>
                        </button>
                        <button type="submit" class="btn btn-primary">
                            <s:text name="common.button.save"/>
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>

With the x-effect tag, I tried to log the value of the the detected item to be selected in the select tag and the value itself.

this is the console output when the modal is open:

// first loop

<empty string>

code: RESULTAT type: <empty string>
code: INCIDENCE type: <empty string>

code: REALISATION type: <empty string>

// second loop    

REALISATION

code: RESULTAT type: REALISATION

code: INCIDENCE type: REALISATION

code: REALISATION type: REALISATION 

In the first loop I see the value from my function editIndicateur() is empty so I assume, alpine.s tries to render the modal before the call back and then do a second loop.

Have you an idea why the modal is populate before the value is return by the function and also why it loops a second time?

Thanks for your help

how do I get multiple a tag href links (in form of an array) from inside an iframe (puppeteer)?

Pretty new to coding, which is why this question might be easily answered, but after scanning the internet for 2 days now and still not having a real solution, i thought I’d just ask here.

So, as the title explains, I have an iframe inside a website I want to scrape with an id attribute (we’ll just call it iframeid) and somewhere inside this iframe I have a div container with a class attribute (we’ll call it divclass) that contains – besides other elements – multiple <a> tags. My goal is to get an array in which all the links from those <a> tags are listed, put to date I only achieved the following through researching and a bit of luck:

const elementHandle = await page.waitForSelector('iframe#iframeid');
const frame = await elementHandle.contentFrame();
await frame.waitForSelector('div[class=divclass] a');
var x = 2; //a var to determine which a tag I want
const oneA= await frame.$('div[class=entryLayer] a:nth-child(' + x + ')');
const link = await (await oneA.getProperty('href'))._remoteObject.value;
console.log(link);

What it does is it takes a variable and pulls the link of its according <a> tag, but I can’t figure out how to put it in a loop and besides that, the amount of <a> tags varies, which makes the loop for me to code even harder.

Wouldn’t it even be possible to leave out the loop completely? I found similar stackoverflow questions, but one for example only had one <a> tag which seems to change the code completely.

At the end I just want a working piece of code that I as a newbie can understand but is fairly compact at the same time.
Thanks for helping in advance!

Three.js: how to add a custom URL on a loaded GLTF model

I have a galaxy made of 3 planets and a spaceship and I want all of them to be clickable to load another page. I managed to do so with the 3 planets adding planet.userData = {URL: "my.html"}; but not with the spaceship, which is a GLTF loaded model.

This is how I loaded the spaceship:

const loader = new GLTFLoader();
            loader.load('models/spaceship.glb', function(gltf) {

                const spaceship = gltf.scene;
            
                spaceship.scale.set(0.08, 0.08, 0.08);
                spaceship.userData = {URL: "my.html"}; //Adding the URL here
                objects.push(spaceship); //This is for raycasting
                scene.add(spaceship);
                
                
            }, undefined, function(error){
                console.error(error);
            });

And this is the function for the Mouse Down event:

function onDocumentMouseDown(){

                mouse.x = (event.clientX/window.innerWidth)*2-1;
                mouse.y = -(event.clientY/window.innerHeight)*2+1; 

                const raycaster = new THREE.Raycaster();
                raycaster.setFromCamera(mouse, camera);
                const intersects = raycaster.intersectObjects(objects, true);

                if ( intersects.length > 0 ) {
                    window.open(intersects[0].object.userData.URL); // <-- Doesn't work
                }

            }

When clicking on the spaceship the URL value is “undefined”. I’m sure there is another way to do so but I can’t find any solution. Thank you so much in advance to anyone helping!

After signin on next AUTJ I am redirected to the localhost instead of my website URL

I am working on an e commerce store , on the click of sign in , it pops up the google sign in , once i sign in with google . It redirects to local host instead of the wesbsite url . How do i fix it
I have a feeling it is cause of my

 NEXTAUTH_URL = HTTP://LOCALHOST

below is the code

import { useSelector } from "react-redux";
import Header from "../components/Header";
import CheckoutProduct from "../components/CheckoutProduct";
import { selectItems, selectTotal } from "../slices/basketSlice";
import Currency from "react-currency-formatter";
import { signIn, signOut, useSession } from "next-auth/client"



function Checkout() {
    const items = useSelector(selectItems);
    const total = useSelector(selectTotal)
    const [session] = useSession();



 <button role="link"
                                onClick={signIn} className={`button mt-2  font-semibold pl-5 pr-5 `}>
                                    SIGN IN
                            </button>
                            <button
                                disabled={!session} className={`button mt-2 ${!session && 'from-gray-300 to-gray-500 border-gray-200 text-gray-300 cursor cursor-not-allowed'}`}
                            >
                                {!session ? "signin to checkout" : "Pay with card"}


                            </button>

   )}
                </div>
            </main>
        </div>
    )
}

export default Checkout

HERE IS MY NEXTAUTH FILE

import NextAuth from "next-auth"
import Providers from "next-auth/providers";
export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    Providers.Google({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
    }),
    // ...add more providers here
  ],
})

HERE IS MY ENV FILE

# Authentication
GOOGLE_ID=###########################################
GOOGLE_SECRET=############################################
NEXTAUTH_URL=http://localhost:3000

I have a feeling it is cause of my NEXTAUTH_URL = HTTP://LOCALHOST

Sign in with apple id keeps popping up, does not sign in

I had an react native app. I configured it for ios and ran it. The app also uses in app purchases library(react-native-iap). When I’m using app it just keeps popping up for a sign in with apple modal that requires apple id and password. When i try to login with my apple e-mail registered for apple developer account it does nothing whether return E_UNKNOWN error. I am able to get purchase history or get products from apple but i can not login. I want this error disappear. If anyone can help me.

Here is some logs i catch

 Possible Unhandled Promise Rejection (id: 0):
Error: UNKNOWN_ERROR
promiseMethodWrapper@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:2576:45
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:186002:49
step@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:185692:25
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:185622:20
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:185594:73
tryCallTwo@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:28723:9
doResolve@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:28887:25
Promise@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:28746:14
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:185573:36
ios@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:185999:25
requestSubscription@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:186013:27
onPress@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:268892:52
_performTransitionSideEffects@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:64050:22
_receiveSignal@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:63992:45
onResponderRelease@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:63888:34
invokeGuardedCallbackProd@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3680:21
invokeGuardedCallback@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3784:42
invokeGuardedCallbackAndCatchFirstError@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3788:36
executeDispatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3866:48
executeDispatchesInOrder@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3886:26
executeDispatchesAndRelease@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5146:35
forEach@[native code]
forEachAccumulated@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:4417:22
runEventsInBatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5170:27
runExtractedPluginEventsInBatch@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5250:25
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5225:42
batchedUpdates$1@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:17287:20
batchedUpdates@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5132:36
_receiveRootNodeIDEvent@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5224:23
receiveTouches@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:5278:34
__callFunction@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3089:36
@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:2813:31
__guard@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:3040:15
callFunctionReturnFlushedQueue@http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&modulesOnly=false&runModule=true&app=org.reactjs.native.example.cnhdeneme:2812:21
callFunctionReturnFlushedQueue@[native code]

Is there a limit on how many divs a vue component has to have so it can be displayed as a microfrontend?

I made this webpack module federation microfrontend project that consists a vue project that contains a vue component that should be displayed in another vue project.

So I have a vue component like this and it doesn’t get displayed:

    <div class="column is-6 is-offset-3">
      <div class="box">
        <div class="block">
          <h1 class="title">Title</h1>
        </div>
        <div class="columns">
          <div class="column has-text-grey">by x</div>
          <div class="column has-text-grey">12/12/32 12:34</div>
        </div>
        <div class="block">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa
          voluptatem harum praesentium quas voluptatibus nostrum debitis totam
          tempore, et dolor unde incidunt hic recusandae ipsa facilis quaerat
          quod sequi nulla?
        </div>
        <div class="block">
          <div class="tags">
            <span class="tag">tag </span>
            <span class="tag">tag </span>
            <span class="tag">tag </span>
            <span class="tag">tag </span>
          </div>
        </div>
      </div>
    </div>
  </div>

I have noticed that if I remove some divs it does eventually get displayed, like this:

<template>
  <div class="columns">
    <div class="column is-6 is-offset-3">
      <div class="box">
        <div class="block">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Culpa
          voluptatem harum praesentium quas voluptatibus nostrum debitis totam
          tempore, et dolor unde incidunt hic recusandae ipsa facilis quaerat
          quod sequi nulla?
        </div>
      </div>
    </div>
  </div>
</template>

Is there a limit?, how can I change it?

this are the webpack configs:
for the project that provides data:

const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = (env = {}) => ({
  mode: "development",
  cache: false,
  devtool: "source-map",
  optimization: {
    minimize: false,
  },
  target: "web",
  entry: path.resolve(__dirname, "./src/main.js"),
  // output: {
  //   path: path.resolve(__dirname, './dist'),
  //   publicPath: '/dist/'
  // },
  output: {
    publicPath: "auto",
  },
  resolve: {
    extensions: [".vue", ".jsx", ".js", ".json"],
    alias: {
      // this isn't technically needed, since the default `vue` entry for bundlers
      // is a simple `export * from '@vue/runtime-dom`. However having this
      // extra re-export somehow causes webpack to always invalidate the module
      // on the first HMR update and causes the page to reload.
      vue: "@vue/runtime-dom",
    },
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        use: "vue-loader",
      },
      {
        test: /.png$/,
        use: {
          loader: "url-loader",
          options: { limit: 8192 },
        },
      },
      {
        test: /.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {},
          },
          "css-loader",
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
    new ModuleFederationPlugin({
      name: "home",
      filename: "remoteEntry.js",
      remotes: {
        home: "home@http://localhost:8002/remoteEntry.js",
      },
      exposes: {
        "./Content": "./src/components/Content",
        "./Button": "./src/components/Button",
        "./Post": "./src/components/Post",
        "./Test": "./src/components/Test"
      },
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "./index.html"),
    }),
    new VueLoaderPlugin(),
  ],
  devServer: {
    static: {
      directory: path.join(__dirname),
    },
    compress: true,
    port: 8002,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    },
  },
});

For the project that reads data:

const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = (env = {}) => ({
  mode: "development",
  cache: false,
  devtool: "source-map",
  optimization: {
    minimize: false,
  },
  target: "web",
  entry: path.resolve(__dirname, "./src/main.js"),
  output: {
    publicPath: "auto",
  },
  resolve: {
    extensions: [".vue", ".jsx", ".js", ".json"],
    alias: {
      // this isn't technically needed, since the default `vue` entry for bundlers
      // is a simple `export * from '@vue/runtime-dom`. However having this
      // extra re-export somehow causes webpack to always invalidate the module
      // on the first HMR update and causes the page to reload.
      vue: "@vue/runtime-dom",
    },
  },
  module: {
    rules: [
      {
        test: /.vue$/,
        use: "vue-loader",
      },
      {
        test: /.png$/,
        use: {
          loader: "url-loader",
          options: { limit: 8192 },
        },
      },
      {
        test: /.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {},
          },
          "css-loader",
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
    }),
    new ModuleFederationPlugin({
      name: "layout",
      filename: "remoteEntry.js",
      remotes: {
        home: "home@http://localhost:8002/remoteEntry.js",
      },
      exposes: {},
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "./index.html"),
      chunks: ["main"],
    }),
    new VueLoaderPlugin(),
  ],
  devServer: {
    static: {
      directory: path.join(__dirname),
    },
    compress: true,
    port: 8001,
    hot: true,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    },
  },
});

Pictures Wall with using InputFile multiple upload

There is a nice example with picture wall. However in example third party service is used that is not that much help in case there is a need to store pictures locally or in DB. How to implement the same in case of pictures would be stored locally with using native InputFile?

I saw there is a solution with single image file and I am already using it in my project, that is working nice. However how to implement the same in case there are multiple files?

This is what I have got so far, but I am missing gallery layout in case of multiple images. Also I am missing preview option and remove option. How to get these icons on image hover? How to make images appear like in gallery?

  <span class="ant-upload-picture-card-wrapper" >
    <label class="avatar-uploader" for="upload">
      <div class="ant-upload ant-upload-select-picture-card ant-upload-select">
        <div tabindex="0" class="ant-upload" style="position:relative;">
          <InputFile OnChange="@this.OnFileSelection" multiple id="upload" hidden accept=".png,.jpg,.jpeg,.gif" />
          <div class="row">
            @if (this.ImgUrls.Any())
            {
              @foreach (var url in this.ImgUrls)
              {
                <div>
                  <img src="@url" alt="avatar" style="width: 100%" />
                </div>
              }
            }
            else
            {
              <div>
                <Icon Spin="this.loading" Type="@(this.loading?"Loading":"plus")"></Icon>
                <div className="ant-upload-text">Upload</div>
              </div>
            }
          </div>
        </div>
      </div>
    </label>
  </span>

Here is what I am trying to achieve:

enter image description here

Implement order select and display using document.querySelectorAll in Angular

This is a part of an e-commerce app in which customers can select an order and go to checkout. A group of similar buttons that have a data- attribute, with respective extensions to data-something. I am able to implement this well in JavaScript and Html 5. I want to know how to achieve exactly the same using Angular.
Here I only show a small part of HTML code to maintain simplicity.

        <div class="financials oriental">
          <div class="pf-icons">
            <i class="fab"></i>
          </div>

          <table>
            <caption class="text-white">
              Package Brand & Details.
            </caption>
            <thead>
              <tr>
                <th colspan="2">
                  <h2 class="product-header">Aladdin Basic</h2>
                </th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td><h3 class="table-key text-white">Minimum</h3></td>
                <td>
                  <h3 class="table-value min-amount text-white">K 50</h3>
                </td>
              </tr>
              <tr>
                <td><h3 class="table-key even">Maximum</h3></td>
                <td><h3 class="table-value even max-amount">Unlimited</h3></td>
              </tr>
              <tr>
                <td><h3 class="table-key text-white">Interest</h3></td>
                <td>
                  <h3 class="table-value text-white percentage-earning">
                    100% in 48Hrs.
                  </h3>
                </td>
              </tr>
            </tbody>
          </table>

          <button data-plan="aladdin">Select Plan</button>
        </div>

Below is JavaScript I wish to implement in Angular,

// Select Plan Logic
    const planButtons = document.querySelectorAll("button[data-plan]");

    planButtons.forEach((button) => {
      button.addEventListener("click", (e) => {
        const button = e.currentTarget;
        const container = button.parentNode;
        const grandParent = container.parentNode;

        const plan = {
          id: button.getAttribute("data-plan"),
          containerClassList: container.getAttribute("class"),
          // iconClasses: container.querySelector(".fas").getAttribute("class"),
          title: container.querySelector(".product-header").innerText,
          minAmount: container.querySelector(".min-amount").innerText,
          maxAmount: container.querySelector(".max-amount").innerText,
          percentageEarning: container.querySelector(".percentage-earning")
            .innerText,
        };

        localStorage.setItem("plan", JSON.stringify(plan));

        const url = window.location.href.split("dashboard", 1)[0];
        window.location.href = `${url}plan`;
      });
    });

    displayOrder = () => {
      const order = localStorage.getItem("plan");
      const submitInput = document.getElementById("submittedAmount");
      const planInput = document.getElementById("plan");

      if (order) {
        const packageOrder = JSON.parse(order);

        const package = document.querySelector(".financials");

        const title = package.querySelector(".product-header"),
          icon = package.querySelector(".fas"),
          minAmount = package.querySelector(".min-amount"),
          maxAmount = package.querySelector(".max-amount"),
          percentageEarning = package.querySelector(".percentage-earning"),
          duration = package.querySelector(".duration");

        package.setAttribute("class", `${packageOrder.containerClassList}`);
        icon.setAttribute("class", `${packageOrder.iconClasses}`);
        title.innerText = packageOrder.title;
        minAmount.innerText = packageOrder.minAmount;
        maxAmount.innerText = packageOrder.maxAmount;
        percentageEarning.innerText = packageOrder.percentageEarning;

        whitenText = () => {
          // Make Text White for Package visibility
          const dataArr = document.querySelectorAll("h3");

          dataArr.forEach((item) => {
            item.classList.add("text-white");
          });
        };

        if (title.innerText === "PP1") {
          planInput.value = "pp1";
          submitInput.setAttribute("placeholder", "Enter amount 100");
          whitenText();
        } else if (title.innerText === "PP2") {
          planInput.value = "pp2";
          submitInput.setAttribute("placeholder", "Enter amount 200");
        } else if (title.innerText === "PP3") {
          planInput.value = "pp3";
          submitInput.setAttribute("placeholder", "Enter amount 500");
          whitenText();
        } else if (title.innerText === "SP1") {
          planInput.value = "sp1";
          submitInput.setAttribute("placeholder", "Enter amount 200");
          whitenText();
        } else if (title.innerText === "UP1") {
          planInput.value = "up1";
          submitInput.setAttribute("placeholder", "Enter amount 500");
          whitenText();
        } else if (title.innerText === "UP2") {
          planInput.value = "up2";
          submitInput.setAttribute("placeholder", "Enter amount 1000");
          whitenText();
        } else if (title.innerText === "UP3") {
          planInput.value = "up3";
          submitInput.setAttribute("placeholder", "Enter amount 2000");
          whitenText();
        }
      }
    };

    if (urlPath === "/plan") {
      displayOrder();
    }

How to get the products ID, Impressions and Click from Google Ads using Ads Script?

I am working with Google Ads Scripts. Based on my use case, I need to get the impressions, clicks, and other statistics about the products I have in my Google Ads account.

These product statistics will be analyzed in the script and based on certain criteria a Google Sheet document will be updated. The script goes like, retrieving all products (along with their statistics) from Google Ads account, see if the products impression and clicks meet a category (30 Impression, 1 click = Category “A”, 20 Impressions, 0 Clicks = “Category B”), determines the product category, open Google Sheet hosted on Google Drive and updates the Category column in the Sheet based on product name or id.

Currently, I am facing an issue with retrieving Products and their statistics from Google Ads Account using Ads Script. I used the following code snippets to look for products but found no method or class that would help me achieve my desired results. I can only retrieve the productGroups, AdGroups, and Campaigns but none of them allow me to extract individual products.

    function productGroup(){
      var prodGroupIter = AdsApp.productGroups().get();
      while (prodGroupIter.hasNext()){
        var prodGroup = prodGroupIter.next();
        var children = prodGroup.getCampaign().getName()
        Logger.log(children);
        while (children.hasNext()){
          Logger.log(children);
        }
      }
    }

    function adGroup() {
      var adGroupIterator = AdsApp.adGroups().get();
  
      while (adGroupIterator.hasNext()) {
        var adGroup = adGroupIterator.next();
        var products = adGroup.ads().get().next().
        Logger.log("adGroup: ")
        Logger.log(adGroup.getName());
        Logger.log(addGroupName);
      }
    }

    function campaign(){
      var campIter = AdsApp.campaigns().get();
      while (campIter.hasNext()){
        var campaign = campIter.next().ads().get();
        while(campaign.hasNext()){
          Logger.log(campaign.next().getStatsFor("LAST_30_DAYS"));
        }
      }
    }

    function sheet() {
      var sheetURL = "https://docs.google.com/spreadsheets/d/1W0zhRrQa1P7qjQf0eXXw-QzdcPKAlDPiVBOcIVEfDgw/edit#gid=1428103052";
      var sheet = SpreadsheetApp.openByUrl(sheetURL);
    }

    function main(){
      campaign();
      adGroup();
      productGroup();
    }

I then reached out to the Ads Script support team and found out that it is not possible. But they suggested that I can use Shopping Performance Report, Product Partition Report, shopping_performance_view or product_group_view. They are part of AdWord API, and I do not know how to work with them.

So, I am looking for a Google Ads Script that would help me get a list of products (with detailed statistics) from Googe Ads and I am stuck with how to use the above-mentioned AdWord reporting endpoints to do it.

Here is the list of products in my Google Ads Account. They are 107 products along with their statistics.
Screenshot - Google Ads Products

Please, help with at least comments, ideas, and suggestions, I can write code but I am not sure what I am missing on