Draft.js. How can I update block atomic:image src later on for example article save? - draftjs

I am having trouble updating my image blocks in editorState in draft.js.
I want to change atomic:image src on button save.
So the src is for example now blob:http://localhost:3000/7661d307-871b-4039-b7dd-6efc2701b623
but I would like to update to src to for example /uploads-from-my-server/test.png
onSave(e) {
e.preventDefault();
const { editorState } = this.state;
const contentState = editorState.getCurrentContent();
editorState.getCurrentContent().getBlockMap().map((block) => {
const type = block.getType();
if (type === 'atomic:image') {
const rangeToReplace = new SelectionState({
anchorKey: block.getKey(),
focusKey: block.getKey(),
});
Modifier.replaceText(contentState, rangeToReplace, '/uploads-from-my-server/test.png');
const newContentState = editorState.getCurrentContent();
this.setState({ editorState: newContentState });
}
return true;
});
I know I can access src string with block.getData().get('src') but I cant set though
Thank you for your awesome editor

I was struggling with a similar problem, I ended up converting the content state to raw array using convertToRaw and then updating it manually and use convertFromRaw and set the new state :
import {EditorState, ContentState, convertToRaw, convertFromRaw /*, ...*/} from 'draft-js';
// ...
onSave(e) {
e.preventDefault();
const { editorState } = this.state;
const contentState = editorState.getCurrentContent();
let rawContent = convertToRaw(contentState);
for(let i = 0; i < rawContent.blocks.length; i++) {
let b = rawContent.blocks[i];
if(b['type'] !== "unstyled" && b.entityRanges.length === 1) {
const entityKey = b['entityRanges'][0]['key'];
const entityMap = rawContent['entityMap'][entityKey];
if(entityMap["type"] === "image") {
rawContent['entityMap'][entityKey]['data']['src'] = '/uploads-from-my-server/test.png';
}
}
}
const newContentState = convertFromRaw(rawContent);
const newEditorState = EditorState.push(this.state.editorState, newContentState, 'update-contentState');
this.setState({editorState: newEditorState});
}
Note: This is not a fully working example, it's just a starting point. Hope it helps :)

Related

Javascript class how to make it, with a constructor?

Also what are these:
`from selenium import webdriver`
\`def hladaj(vyraz):
driver = webdriver.Chrome()
driver.get('https://www.bing.com/')
search_bar = driver.find_element_by_name('q')
search_bar.send_keys(vyraz)
search_bar.submit()
def otvor(n):
result_links = driver.find_elements_by_css_selector('.b_algo a')
result_links\[n-1\].click()
class Laptop {
constructor(vyrobca, model, rocnik) {
this.vyrobca = vyrobca;
this.model = model;
this.rocnik = rocnik;
}
vypis() {
return `${this.vyrobca},${this.model},${this.rocnik}`;
}
}\`
`<script> // Ziskanie tlacidla var button = document.getElementById("remove"); // Pridanie event listenera na stlacenie tlacidla button.addEventListener("click", function() { // Ziskanie vsetkych elementov s triedou "col" var elements = document.getElementsByClassName("col"); // Prechod cez vsetky elementy for (var i = 0; i < elements.length; i++) { // Zistenie textu v elemente var text = elements[i].textContent; // Ak element obsahuje retazec "Row" if (text.includes("Row")) { // Zmazanie elementu elements[i].parentNode.removeChild(elements[i]); } } }); </script>`
`function o2a(obj){ let final= []; final = Object.keys(objs).map(key=> { let arr = []; arr.push(key); arr.push(obj[key]); return arr; }) return final; }`
`function a2o(arr){ let obj = {} arr.forEach(item=> { obj[item[0]] = item[1]; }); return obj; `
\`import React, { useState } from "react";
function Inp() {
const \[value, setValue\] = useState("");
return (
\<input
value={value}
onChange={(e) =\> setValue(e.target.value)}
placeholder="Input value"
/\>
);
}
function But() {
const \[clicked, setClicked\] = useState(false);
return (
\<button onClick={() =\> setClicked(true)}\>Submit\</button\>
);
}
function Out({ value }) {
return \<div\>{value}\</div\>;
}
function App() {
const \[inputValue, setInputValue\] = useState("");
const handleClick = () =\> {
setInputValue(inputValue);
};
return (
\<div\>
\<Inp /\>
\<But onClick={handleClick} /\>
\<Out value={inputValue} /\>
\</div\>
);
}
export default App;\`
Jazyk javascript bezi defaultne na jednom jadre. Na rozhodnutie toho kedy spusti ktoru funkciu, pouziva event Loop.
Multi-threaded funkcionalitu vieme dosiahnut ponocou builtin API ktore sa nazyva Webliorker. Tento API umoznuje beh paralelnych procesov.
A este tab a browser maju vlastne javascript thready a tak aj prehliadaci je multi thread
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8084 });
let counter = 0;
setInterval(() => {
counter += 2;
}, 2000);
wss.on('connection', (ws) => {
console.log('Connected');
setInterval(() => {
ws.send(counter.toString());
}, 2000);
});
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:8084');
ws.on('message', (message) => {
const counter = parseInt(message);
const span = document.createElement('span');
span.textContent = `Aktualny stav pocitadla: ${counter}`;
document.body.appendChild(span);
});
1.prehliada precita kod ako text
2. parsuje to na AST (Abstract Syntax Tree)
3.optimalizuje to
4. vnutorne si ho za behu to kompiluje do bytecode a za behu kontroluje. Pocas kontroly sa engine pozera ze ktore funkcie su ako casto volane, alebo vypoctovo narocne a podla toho ich optimalizuje
const http = require('http');
const fs = require('fs');
const server = http.createServer((req, res)=>{
if (req.method !== 'GET') {
res.end({"error": "error"}")
}else{
if (req.url === '/indexFile'){
fs.readFile('./index.html', function (err, html) {
if (err) {
throw err;
res.writeHeader (200, "Content-Type": "text/html"});
res.write(html);
}
res.end();
if(req.url === '/response'){
const data = fetch('http://esh.op/order').then(res => res.data);
res.writeHead (200, {'Content-Type': 'application/json'});
res.end(JSON.stringify(data));
}
}
});
server.listen(8080)
function conv(str){
str = str.replaceAll(',',"");
str = str.replaceAll(';', "");
str = str.replaceAll('.',"");
return str.split('').sort((a,b) => b.localeCompare(a))
}

how to update a collection if you already called it MongoDB Mongoos

Ok so I have a problem in which I use a collection to gather some ratings data and work with it, by the time I finish the rating update process, I have new ratings that I would like to update the collection with. However I can't call update because I get the error "Cannot overwrite model once compiled." I understand that I already called once the model to work with the data and that's why I get the error. is there any way I can update the collection? Or I will just have to workaround by creating a new collection with the latest rating, and then matching the latest ratings collection with the one I use to work with the data.
This is my code
let calculateRating = async () => {
const getData = await matchesCollection().find().lean();
const playerCollection = await playersCollection();
const getDataPlayer = await playerCollection.find().lean();
let gamesCounting = [];
getDataPlayer.forEach((player) => {
player.makePlayer = ranking.makePlayer(1500);
});
for (let i = 0; i < getData.length; i++) {
const resultA = getDataPlayer.findIndex(({ userId }, index) => {
if (userId === getData[i].userA) {
return index;
}
});
const resultB = getDataPlayer.findIndex(
({ userId }) => userId === getData[i].userB
);
const winner = getData[i].winner;
if (getDataPlayer[resultA] === undefined) {
continue;
} else if (getDataPlayer[resultB] === undefined) {
continue;
}
gamesCounting.push([
getDataPlayer[resultA].makePlayer,
getDataPlayer[resultB].makePlayer,
winner,
]);
}
ranking.updateRatings(gamesCounting);
let ratingsUpdate = [];
getDataPlayer.forEach((item) => {
let newRating = item.makePlayer.getRating();
let newDeviation = item.makePlayer.getRd();
let newVolatility = item.makePlayer.getVol();
item.rating = newRating;
item.rd = newDeviation;
item.vol = newVolatility;
ratingsUpdate.push(item);
});
};
I try the work around with creating the new collection

Batches with BulkWriter in google firestore

Does anyone know why this does not work, what am I doing wrong here. It get stuck after the console.log "after read stream"
I am trying to read a bunch of files, convert it to json and upload with bulkwriter to firestore.
After each 400 document I am calling close to write them to firestore and then I am creating a new bulkwriter
I also tried awaiting bulkWriter.create(eventDoc, {}) but it does not work. It also get stuck and there is no error. Why is this ? the create method returns a promise.
Why can't it be awaited ?
https://googleapis.dev/nodejs/firestore/latest/BulkWriter.html#create
The idea is to process 1 file at the time and it can contains tens of thousands of rows which needs to be uploaded to firestore
I am calling this method in for...of loop and awaiting the processBatch method
Any help highly appreciated
async processBatch(document: string, file: string): Promise<void> {
const db = admin.firestore();
console.log('start: ', document);
let bulkWriter;
const writeBatchLimit = 400;
let documentsInBatch = 0;
let totalInDocument = 0;
const eventsCollectionRef = db.collection('events');
const eventDoc = eventsCollectionRef.doc(document);
return new Promise((resolve, reject) => {
console.log('promise');
bulkWriter = db.bulkWriter();
const csvStream = fs.createReadStream(file);
console.log('after read stream');
bulkWriter.create(eventDoc, {})
.then(result => {
console.log('Successfully: ', result);
csvStream.pipe(csvParser())
.on('data', row => {
console.log('row');
bulkWriter.create(eventDoc.collection('event').doc(), row);
documentsInBatch++;
if (documentsInBatch > writeBatchLimit) {
bulkWriter.close();
totalInDocument = + documentsInBatch;
documentsInBatch = 0;
bulkWriter = db.bulkWriter();
}
})
.on('end', () => {
console.log('file: ', file + ', totalInDocument: ', totalInDocument);
resolve();
});
})
.catch(err => {
console.log('Failed: ', err);
reject();
});
});
}
This seems to work:
async processBatch(document: string, file: string): Promise<void> {
const db = admin.firestore();
console.log(`start: ${document}`);
let bulkWriter;
const writeBatchLimit = 400;
let documentsInBatch = 0;
let numOfBatches = 0;
let totalInDocument = 0;
const eventsCollectionRef = db.collection('events');
const eventDoc = eventsCollectionRef.doc(document);
bulkWriter = db.bulkWriter();
const csvStream = fs.createReadStream(file);
bulkWriter.create(eventDoc, {});
csvStream.pipe(csvParser())
.on('data', row => {
bulkWriter.create(eventDoc.collection('event').doc(), row);
documentsInBatch++;
if (documentsInBatch > writeBatchLimit) {
numOfBatches++;
totalInDocument += documentsInBatch;
documentsInBatch = 0;
bulkWriter.close();
console.log(`Committing batch ${numOfBatches}, cumulative: ${totalInDocument}`);
bulkWriter = db.bulkWriter();
}
})
.on('end', () => {
console.log(`file: ${file}, totalInDocument: ${totalInDocument}`);
});
}

How to simplify the search query parameter?

The problem
I have a movie database with the indexName: 'movies'.
Let's say my query is John then the domain is domain.tld/?movies[query]=John.
I want to simplify the search query parameter to domain.tld/?keywords=John. How can I do that?
What I already know
After reading through the docs I know that I have to modify the createURL and the parseURL somehow:
createURL({ qsModule, location, routeState }) {
const { origin, pathname, hash } = location;
const indexState = routeState['movies'] || {};
const queryString = qsModule.stringify(routeState);
if (!indexState.query) {
return `${origin}${pathname}${hash}`;
}
return `${origin}${pathname}?${queryString}${hash}`;
},
...
parseURL({ qsModule, location }) {
return qsModule.parse(location.search.slice(1));
},
After some try and error here is a solution:
createURL({ qsModule, location, routeState }) {
const { origin, pathname, hash } = location;
const indexState = routeState['movies'] || {}; // routeState[indexName]
//const queryString = qsModule.stringify(routeState); // default -> movies[query]
const queryString = 'keywords=' + encodeURIComponent(indexState.query); // NEW
if (!indexState.query) {
return `${origin}${pathname}${hash}`;
}
return `${origin}${pathname}?${queryString}${hash}`;
},
...
parseURL({ qsModule, location }) {
//return qsModule.parse(location.search.slice(1)); // default: e.g. movies%5Bquery%5D=john
const query = location.search.match(/=(.*)/g) || []; // NEW
const queryString = 'movies%5Bquery%5D' + query[0]; // NEW
return qsModule.parse(queryString); // NEW
},

how can i update a field in firestore database with google cloud function when another field changes?

I want to write a simple google cloud function for firestore database which updates a field in a document when another field changes at the same document. The triggered field is named "copper" and the updates will be done to the field "coppervalue". I wrote a simple function for this, it doesnt give any error but it doesnt update the field "coppervalue" either, so i would like to learn where i am doing wrong.
Here is my cloud function code:
const functions = require('firebase-functions');
exports.copperupdate = functions.firestore
.document("/kullanici/{uid}")
.onUpdate((change,context) => {
const newfieldvalue = change.after.data();
const fieldname = newfieldvalue.name;
if(fieldname==="copper"){
const d = new Date();
const currenttime = d.getTime();
const coppervalue = snap.data()['coppervalue'];
const copperdate = snap.data()['copperdate'];
const copperdec = (currenttime-copperdate)/1000
const copper_real= (copperdec*copper/60)+coppervalue;
const sonuccopper = Math.trunc(copper_real)
return change.after.ref.set({
coppervalue: sonuccopper
}, {merge: true});
}else{
return false;
}
});
Thanks in advance.
Finally figured it out;
My mistake was i thought newfieldvalue.name was accessing the name of the field instead it was accessing "name" field so i made a few changes, here is the code
const functions = require('firebase-functions');
exports.copperupdate = functions.firestore
.document("/kullanici/{uid}")
.onUpdate((change,context) => {
const newfieldvalue = change.after.data();
const previousfieldvalue = change.before.data();
if (newfieldvalue.copper === previousfieldvalue.copper){
return false;
}else{
const d = new Date();
const currenttime = d.getTime();
const copper = newfieldvalue.copper;
const coppervalue = newfieldvalue.coppervalue;
const copperdate = newfieldvalue.copperdate;
const copperdec = (currenttime-copperdate)/1000
const copper_real= (copperdec*copper/60)+coppervalue;
const sonuccopper = Math.trunc(copper_real)
return change.after.ref.set({
coppervalue: sonuccopper
}, {merge: true});
}
});