Re-render React component from Laravel blade
I am using React component inside of Laravel blade, I am using the following attributes
<div class="card" data-controller="react" data-react-widget-type="Data" data-react-props="someData"></div>
It works fine except when I change the DOM element after an event and add new props, then the React component will not be rendered again and the new props will not be used in the component.
The scenario in short is, I am uploading a file using jQuery, depending on its response, I am updating the DOM element of react widget, then I need to re-render the component.
1 answer
-
answered 2021-02-23 12:02
Nikolai Kiselev
You can upload a file and change the state of the React component instead of its properties. Otherwise you need to write your own listener, that watches for changes in document's element and triggers re-render (which is inefficient).
See also questions close to this topic
-
loading different content on single Html page with the use of JavaScript
I am very new to HTML, CSS and JavaScript and designing a web site that is a text-based game. I have attached an example http://monsterbreeder.com/ my question is I want multiple different pages loaded on a single HTML document without changing the URL of the page with the help of JavaScript. I want some recommendations of tutorials or videos which might help me understand how it is implemented,
Any help will be appreciated
thank you
-
How Can I Update the property of an object based on another one updated at the same time - zustand?
I have a product and i want to get the total price of this product based on quantity, I'm using zustand for state management.
here's a function I used to update the state.
export const useCartProduct = create<CartProductsProp>( devtools( persist( (set) => ({ incrementProductQuantity: (product: ProductProps) => { set((prev) => { console.log('@userQuantity-product', product.userQuantity); let currentCart = prev.cartProducts.map((cartProduct) => cartProduct.id === product.id ? { ...cartProduct, userQuantity: cartProduct.userQuantity + 1, productTotalPrice: cartProduct.userQuantity * cartProduct.price, // here's the issue "the userQuantity not updated and return the prev value". } : cartProduct, ); return { cartProducts: currentCart, }; }); }, }), ), ), );
the issue here
productTotalPrice: cartProduct.userQuantity * cartProduct.price
"the
userQuantity
not updated and return the prev value".So what I tried is like this
productTotalPrice: (cartProduct.userQuantity + 1) * cartProduct.price,
that's return the correct quantity 'updated one', So is others way to fix it?
-
How to use enter to append my <li> element to my list?
So right now I have a working to-do list where in order to add a list item, you have to click a button. I wish to also allow the user to hit "enter" in order to do the same thing as the button.
Below is the js code I used to create a new li element and append it to my list.
function newElement(){ var li = document.createElement('li'); var inputValue = document.getElementById("myInput").value; li.appendChild(document.createTextNode(inputValue)); if (inputValue === '') { alert("You must write something!"); } else { document.getElementById("list").appendChild(li); } document.getElementById("myInput").value = "";
This is my HTML code for the button that runs the newElement() function above.
<input type ="text" id="myInput" placeholder="Type Task Here" > <button class="submitButton" type="button" onclick="newElement()">Add To List</button>
-
Sending formdata from front-end to back end using Axios
i am trying to send an https request from my front-end(react js) to my back-end (nodejs) using axios.This https request has a csv file converted in formData.My code for sending teh request is this:
let formData = new FormData(); formData.append('file', this.state.selectedFiles); //selectedFiles is input from a ui form const {data : QueryResult} = await axios({ method: 'post', url: "https://localhost:3000/...",formData, headers: {'x-observatory-auth': localStorage.getItem("token")}, }); }
I process this in back end using :
function AddSessions(req,res){ let stream = fs.createReadStream("./upload_folder/upload_file.csv"); let csvData = []; let csvStream = fastcsv .parse() .on('error', function(error) { res.status(400).send("Incorrect Data format.Please enter a csv file"); return }) .on("data", function(data) { csvData.push(data); }) .on("end", function() { // remove the first line: header csvData.shift(); let insert_query = "INSERT IGNORE INTO Sessions(SessionID, StationID,PointID, Username, VehicleID, connectionTime,"+ " doneCharginTime, Timezone ,KwhDelivered ,Protocol,Payment ) VALUES ?"; db.query(insert_query, [csvData], (err, db_res) => { if (err) { res.status(400).send("Incorrect Data format for Sessions or File is too big(larger than 1GB)") console.log(err)} else{ let count_query = "SELECT Count(*) as count FROM Sessions"; db.query(count_query, (err1, result) => { if (err1) res.send(err1.message) else { res.status(200).send({SessionsInUploadedFile :db_res.affectedRows + db_res.warningCount , SessionsImported : db_res.affectedRows, TotalSessionsInDatabase :result[0].count}); } }) } }); } ); stream.pipe(csvStream); } } module.exports = AddSessions
The error i get is :
code: 'ER_PARSE_ERROR', errno: 1064, sqlMessage: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1", sqlState: '42000', index: 0, sql: 'INSERT IGNORE INTO Sessions(SessionID, StationID,PointID, Username, VehicleID, connectionTime, doneCharginTime, Timezone ,KwhDelivered ,Protocol,Payment ) VALUES '
and i can't seem to understand what i am doing wrong.
Note that using postman this request can be done fine.I've been stuck in this for way too long and i can;t find a solution so any help would be very welcome.
Thanks in advance.
-
Dynamically use an imported element based on a that elements name passed as a string prop
I’m looking to dynamically clone an imported element based on a prop passed to the component as a string.
I have this component (simplified for this example):
import { foo, fooBar, etc... } from './foo'; const Bar = ({name, ...props}) => { return cloneElement(name, { ...props, }); };
Then I’m using the component in several places like this:
<Bar name="foo"/>
, or<Bar name="fooBar"/>
. I want it to clone the importedfoo
andfooBar
elements from line 1 above, but this doesn’t seem to work, since it just passes the string “foo” tocloneElement()
, not the importedfoo
element.I looked into factory functions (e.g.
React.createFactory()
), but that seems to just move the duplication to another function, and React seems to discourage the use of createFactory in general (they have it labeled as "considered legacy" in their docs).My current solution is to create an object mapping all the imports, but this results in a lot of duplication:
import { foo, fooBar } from './foo'; const foos = { foo: foo, fooBar: fooBar, etc… }; const Bar = ({name, ...props}) => { return cloneElement(foos[name], { ...props, }); };
I'm wondering if there is an easier way.
-
On update show checked category or subcategory laravel
i have this situation on update for a product in laravel i have to fetch all categories and subcategories and if product have categories checked will be inserted into database all done untill here but when i want to show wich one was assigned to this product i don`t know how to do it.
I tried this situation Controller:
$categories = DB::table('categoriis')->where('id_tata', '=', '0')->get(); $subcategories = DB::table('categoriis')->where('id_tata','!=', '0')->get(); return view('back.products.edit', compact('categories', 'subcategories', 'current_cat'));
My view blade file:
@php $arr = array(); foreach ($current_cat as $categoriselected) { array_push($arr, $categoriselected->id); } @endphp @foreach ($categories as $categorie) <input @php if (in_array($categorie->id, $arr)){echo "checked";}else{echo "";} @endphp class="form-check-input" type="checkbox" name="category[]" value="{{ $categorie->id }}" id="cat{{ $categorie->id }}"> @endforeach
Database:
Categories AssocProductsCategory |id|name| |id|product_id|categories_id| |1|Shirt| |1|199|2| |2|Shoes| |2|199|3| |3|Top|
On my view file i have fetch all categories and display it then i got all categories assigned to this product but i dont know how to display wich one was selected for this product, in core php i did it few times but there in laravel its a bit tricky.
-
Laravel send email after records inserted into mysql
I have a cronjob which inserts new records into the database each day. I would like to examine, wheter the record's value is ok or not. If the record is not ok, an email should be sent.
My question is that, should I use notifications or events?
If events should be used, someone could give me simple example regarding how should the Model, Event and the Listener should look like? I would highly appricate that.
-
Getting an error on creating of a laravel project
Hi There im trying to create a project using laravel, but i get this error when doing it.
PS X:\projects> composer create-project laravel/laravel MuxlyRadio Installing laravel/laravel (v8.5.12) - Installing laravel/laravel (v8.5.12): Extracting archive Created project in X:\projects\MuxlyRadio Loading composer repositories with package information Updating dependencies Your requirements could not be resolved to an installable set of packages. Problem 1 - laravel/framework[v8.12.0, ..., 8.x-dev] require league/flysystem ^1.1 -> satisfiable by league/flysystem[1.1.0, ..., 1.x-dev]. - league/flysystem[1.1.0, ..., 1.x-dev] require ext-fileinfo * -> it is missing from your system. Install or enable PHP's fileinfo extension. - Root composer.json requires laravel/framework ^8.12 -> satisfiable by laravel/framework[v8.12.0, ..., 8.x-dev]. To enable extensions, verify that they are enabled in your .ini files: - C:\Program Files (x86)\PHP\v7.4\php.ini You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode. PS X:\projects>
anyone any idea how to fix this?
-
How to create and mount shadow element using Vue2?
I am creating extension for chrome, using VUE2, i have a problem to creating and mounting shadow element, this is what my
main.js
file looks like, i want to create shadow element with idtemplates
and also give it some css class, but when i checktemplates
element is not created? any solution?import Vue from 'vue' import App from './App.vue' import VueRouter from "vue-router" import CKEditor from '@ckeditor/ckeditor5-vue2'; import router from "./router/router" Vue.use(VueRouter) Vue.use(router) Vue.use(CKEditor) const shadowElement = document.createElement('div'); shadowElement.setAttribute("id", "templates"); shadowElement.style.display = "hidden"; // shadowElement.attachShadow({ mode: 'open' }); document.body.appendChild(shadowElement); new Vue({ router, render: h => h(App), }).$mount('#templates')
-
How to get for loop to complete
I have an object I am using to add tooltips on load after a splash screen is closed. The object looks something like this:
layerNameMapping = { "samp_bldgs": {"title": "Sample_Bldgs", "index": 0, "tt": "Approximate center of buildings within BLE areas", "visible": false}, "buildings": { "title": "Buildings", "index": 1, "tt": "Approximate center of buildings within BLE areas", "visible": true}, "buildings_risk_chng": { "title": "Buildings Risk Change", "index": 2, "tt": "Color-coded change of building from effective flood hazard to BLE", "visible": false}, "contours": { "title": "Contours", "index": 3, "tt": "2ft contour lines", "visible": false}, "contours_diced": { "title": "Contours_Diced", "index": 4, "tt": "2ft contour lines", "visible": true}, "modeled_streamline": { "title": "Modeled Streamline", "index": 5, "tt": "Modeled stream centerlines for BLE studies", "visible": true}, "counties": { "title": "Counties", "index": 6, "tt": "County boundaries", "visible": true}, .... }
Basically the code, using
jQuery
to iterate through items in anode selector
object, has a function (tooltipper2
) to check each item against theitem.title
in thelayerNameMapping
. There will always be 4 items in the main node selector (the variable calledbaseElement_map
) on load.$(window).load(function () { $('#myDisclaimerModal').modal('show'); function tooltipper2(name) { var lyr_map = layerNameMapping; var size = Object.keys(lyr_map).length; tt = name; for (i = 0; i < size; i++) { if (lyr_map[Object.keys(lyr_map)[i]].title === name) { tt = lyr_map[Object.keys(lyr_map)[i]].tt; } } return tt; } $('#splash_close_btn').on("click", function () { switcher = true; window.setTimeout(function () { var baseElement_map = document.querySelector('div.esri-legend').querySelectorAll('div.esri-legend__layer-caption'); if (baseElement_map) { for (i = 0; i < baseElement_map.length; i++) { layerName = baseElement_map[i].innerHTML; baseElement_map[i].title = tooltipper2(layerName); } } }, 500); }); });
My goal is to iterate through each of the 4 items on load (while
i < 4
), match the item title to the title in thelayerNameMapping
object and replace the node item's title with the tt (for 'tooltip'). This works, but only on the first item. After going through the first node item.title ("Modeled Streamline") it breaks when debugging in the console and never moves to the next item. Any ideas as to what I am doing incorrectly here? -
How to use shadow DOM with Vue.js2?
I am creating simple chrome extension for Gmail, using Vue.js 2, also i am using shadow DOM to append content when user click to specific button in Gmail inbox form, with Vue3 everything works fine, but I want to solve this problem using Vue2, on page first load extension box appears, but after refresh i can not open it again this is my main.js file
import Vue from 'vue' import App from './App.vue' import VueRouter from "vue-router" import CKEditor from '@ckeditor/ckeditor5-vue2'; import router from "./router/router" Vue.config.productionTip = false const shadowElement = document.createElement('div'); shadowElement.setAttribute("id", "templates"); shadowElement.style.display = "hidden"; document.body.appendChild(shadowElement); Vue.use(VueRouter) Vue.use(router) Vue.use( CKEditor ) new Vue({ router, render: h => h(App), }).$mount('#templates')
and this is my content-src.js component
import Replacer from './Replacer.vue' import Vue from 'vue' import store from '../store/index' const shadowElement = document.createElement('div'); shadowElement.attachShadow({ mode: 'open' }); document.body.appendChild(shadowElement); new Vue({ el: shadowElement, store, // vuetify: new Vuetify(), render: h => h(Replacer), });
this is example for vue.js3 which works just fine
import { createApp } from 'vue' import App from './App.vue' import CKEditor from '@ckeditor/ckeditor5-vue'; import router from "./router/router.js" const app = createApp(App) const shadowElement = document.createElement('div'); shadowElement.setAttribute("id", "templates"); shadowElement.style.display = "hidden"; // shadowElement.attachShadow({ mode: 'open' }); document.body.appendChild(shadowElement); app.use(CKEditor) app.use(router) app.mount("#templates")