How to convert type data buffer to image using typescript and react - html

I'm having problems showing an image brought from the database.
-> First I'll show you how this image is being stored:
Here I do the import and send it to the backend
import profile_default_image from "../../../other/imgs/profile_default_image.png";
resRegister = await register(user_name, user_email, user_password, profile_default_image);
profile_default_image generates a type string with value =/static/media/profile_default_image.a9136072d073801df253.png
This value is stored in the MYSQL database in a BLOB type field.
Below is the profileImage value of a row
-> Now I'll show you what's happening on the front
const [profileImage, setProfileImage] = useState("test");
useEffect(() => {
async function getUser() {
if (id) {
const res = await apiFindUserById(id);
const base64Flag = "data:image/jpeg;base64,";
const b64Image = await Buffer.from(res.data.profileImage.data).toString("base64");
setProfileImage(base64Flag + b64Image);
}
}
getUser();
}, []);
res.data returns the following:
Below I try to put the image on the screen
<div>
<img style={{ width: 200, height: 200, }}
src={profileImage}
alt="test"
/>
</div>
But the only result I have is this:
I gave a console.log in profileImage and it returned the value of: data:image/jpeg;base64,L3N0YXRpYy9tZWRpYS9wcm9maWxlX2RlZmF1bHRfaW1hZ2UuYTkxMzYwNzJkMDczODAxZGYyNTMucG5n, which basically a blank image.
I tried another way to do(found it here on stackoverflow)
const [profileImage, setProfileImage] = useState("test");
const arrayBufferToBase64 = (buffer: any) => {
let binary = "";
let bytes = new Uint8Array(buffer);
let len = bytes.byteLength;
for (let i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
};
useEffect(() => {
async function getUser() {
if (id) {
const res = await apiFindUserById(id);
const imageStr = await arrayBufferToBase64(res.data.profileImage.data);
const base64Flag = "data:image/jpeg;base64,";
setProfileImage(base64Flag + imageStr);
console.log(profileImage);
}
}
getUser();
}, []);
I got the same result.
The original image is a default user avatar.
It could be that the problem is even when I'm storing this image in the database, can anyone help me? I'm very lost.
Thank you very much!!!

Related

Hardhat, ether.js. TypeError: deployer.sendTransaction is not a function error. Trying to execute exactInput UniswapV3 function

Im trying to execute a swap to buy Uni using UniswapV3 interface.
It sends me this error related to the sendTransaction() function and I dont understand why as a lot of examples that I have seen use it this way.
Im using hardhat as you can see and calling the getToken() from another script and deploying on goerli network. Function to check UNI wallet balnceOf() at the end works fine.
Also what advice would you recommend me to improve my code?
This is the code:
const { ethers, getNamedAccounts, network } = require("hardhat")
const {abi: V3SwapRouterABI} = require('#uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
const FEE_SIZE = 3
function encodePath(path, fees) {
if (path.length != fees.length + 1) {
throw new Error('path/fee lengths do not match')
}
let encoded = '0x'
for (let i = 0; i < fees.length; i++) {
// 20 byte encoding of the address
encoded += path[i].slice(2)
// 3 byte encoding of the fee
encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
}
// encode the final token
encoded += path[path.length - 1].slice(2)
return encoded.toLowerCase()
}
async function getToken() {
// const signer = provider.getSigner()
const deadline = Math.floor(Date.now()/1000) + (60*10)
const wethToken= "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
const Uni= "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const UniswapRouter="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
const path = encodePath([wethToken, Uni], [3000])
console.log(path)
const { deployer } = await getNamedAccounts()
const UniV3Contract = await ethers.getContractAt(
V3SwapRouterABI,
UniswapRouter,
deployer
)
const params = {
path: path,
recipient:deployer,
deadline: deadline,
amountIn: ethers.utils.parseEther('0.01'),
amountOutMinimum: 0
}
const encodedData = UniV3Contract.interface.encodeFunctionData("exactInput", [params])
const txArg = {
to: UniswapRouter,
from: deployer,
data: encodedData,
gasLimit: ethers.utils.hexlify(1000000)
}
const tx = await deployer.sendTransaction(txArg)
console.log('tx: ', tx)
const IUni = await ethers.getContractAt(
"IERC20",
Uni,
deployer
)
const UniBlance = await IUni.balanceOf(deployer)
console.log(`Got ${UniBlance.toString()} UNI`)
}
module.exports = { getToken }
Without using the hardhat enviorment:
const {abi: V3SwapRouterABI} = require('#uniswap/v3-periphery/artifacts/contracts/interfaces/ISwapRouter.sol/ISwapRouter.json')
const { ethers } = require("ethers")
require("dotenv").config()
const INFURA_URL_TESTNET = process.env.INFURA_URL_TESTNET
const PRIVATE_KEY = process.env.PRIVATE_KEY
const WALLET_ADDRESS = process.env.WALLET_ADDRESS
// now you can call sendTransaction
const wethToken= "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6"
const Uni= "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984"
const UniswapRouter="0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
const UniV3Contract = new ethers.Contract(
UniswapRouter,
V3SwapRouterABI
)
const provider = new ethers.providers.JsonRpcProvider(INFURA_URL_TESTNET)
const wallet = new ethers.Wallet(PRIVATE_KEY)
const signer = wallet.connect(provider)
const FEE_SIZE = 3
function encodePath(path, fees) {
if (path.length != fees.length + 1) {
throw new Error('path/fee lengths do not match')
}
let encoded = '0x'
for (let i = 0; i < fees.length; i++) {
// 20 byte encoding of the address
encoded += path[i].slice(2)
// 3 byte encoding of the fee
encoded += fees[i].toString(16).padStart(2 * FEE_SIZE, '0')
}
// encode the final token
encoded += path[path.length - 1].slice(2)
return encoded.toLowerCase()
}
async function getToken() {
const path = encodePath([wethToken, Uni], [3000])
const deadline = Math.floor(Date.now()/1000) + (60*10)
const params = {
path: path,
recipient: WALLET_ADDRESS,
deadline: deadline,
amountIn: ethers.utils.parseEther('0.01'),
amountOutMinimum: 0
}
const encodedData = UniV3Contract.interface.encodeFunctionData("exactInput", [params])
const txArg = {
to: UniswapRouter,
from: WALLET_ADDRESS,
data: encodedData,
gasLimit: ethers.utils.hexlify(1000000)
}
const tx = await signer.sendTransaction(txArg)
console.log('tx: ', tx)
const receipt = tx.wait()
console.log('receipt: ', receipt)
}
module.exports = { getToken }
I could not find documentation for getNamedAccounts but when I check the source code, I get this signature
getNamedAccounts: () => Promise<{
[name: string]: Address;
}>;
this just returns an array of account addresses and used in hardhat.config.js
namedAccounts: {
deployer: {
default: 0, // by default take the first account as deployer
1: 0,
},
},
to send the transaction programmatically:
const { ethers } = require("ethers");
const provider = new ethers.providers.JsonRpcProvider(INFURA_TEST_URL);
const wallet = new ethers.Wallet(WALLET_SECRET);
const signer = wallet.connect(provider);
// now you can call sendTransaction
const tx = await signer.sendTransaction(txArg);

Table is not showing data accordingly in Reactjs

I am trying to show the response from API into the react-semantic-ui table. After setting the state with fetch data, I need to place the first-order keys as the column name and then the second-order keys as the row name and the values of the second-order keys will be shown in the table-body. I have done this far which results in doubling the number of cells in each row while setting all cell values with the same data.
class NonProtectedFeatureBias extends Component {
constructor(props){
super(props);
this.state = {
staticPostData:{
dataset_id: 1
},
tableData:{},
tableColumnNames:[],
};
}
renderKeys (data) {
let tcolumn = [];
for(let i=0; i<Object.keys(data).length;i++){
const Obj1 = Object.keys(data)[i];
//console.log(Obj1)
tcolumn.push(Obj1);
}
let col = tcolumn.map(item=>{
return <Table.HeaderCell>{item}</Table.HeaderCell>
})
return col
}
renderValues (data) {
let row=null;
for(let i=0; i<Object.keys(data).length;i++){
const Obj1 = Object.values(data)[i];
let trows = [];
const Obj2 = Object.keys(Obj1).map(item =>{
trows.push(item);
});
let tvalues =[];
const Obj3 = Object.values(Obj1).map(item =>{
tvalues.push(item);
console.log(item)
});
row = trows.map(item=>{
return(
<Table.Row className="cell-current">
<Table.Cell className="cell-width-single">{item}</Table.Cell>
{tvalues.map(val =>{
return <Table.Cell selectable>{val}</Table.Cell>
//console.log(val)
})}
</Table.Row>
)
})
}
return row
}
componentDidMount() {
this.fetchData();
}
fetchData(){
axios.post('http://localhost:5000/GetProxyTable', this.state.staticPostData)
.then((response) =>{
var count = Object.keys(response.data).length;
this.setState({tableData:response.data})
console.log(response.data)
});
}
render(){
return (
<Container style={{height:"250px", backgroundColor:""}}>
<Table definition >
<Table.Header>
<Table.Row className="cell-with-no-padding">
<Table.HeaderCell />
{this.renderKeys(this.state.tableData)}
</Table.Row>
</Table.Header>
<Table.Body>
{this.renderValues(this.state.tableData)}
</Table.Body>
</Table>
</Container>
);
}
}
export default NonProtectedFeatureBias;
This is the response I get from the API
And this is what I want to achieve,
This is what I am getting now,
Is this the right approach to achieve my goal?! I hope there is a much-optimized way to do this. And I am also needed to be able to click on a cell and get the regarding row and column name. Any suggestions or advice will be much appreciated.
your renderValues are mapping through columns and not rows. Plus, you are setting each fake row to the same values, so all 'rows' are equal. lastly, returns the last one, which means last column values.
you can try code below which maps the columns to a rows object first before rendering the rows:
renderValues (data) {
const rows = {}
Object.values(data).forEach(col => {
for (let [key, value] of Object.entries(col)) {
rows[key] = rows[key] ? [...rows[key], value] : [value]
}
})
return Object.entries(rows).map(([item, values]) => (
<Table.Row className="cell-current">
<Table.Cell className="cell-width-single">{item}</Table.Cell>
{ values.map(val => <Table.Cell selectable>{val}</Table.Cell> ) }
</Table.Row>
))
}

How to wait to finish subscribe before moving to next index in for loop in Angular 6

I'm using Angular 6.
I have an array of links and a variable to store fetched information in same order as of array one by one.
Here is what I'm trying to do using for loop.
products: any;
processedItems: Array<any> = [];
private _processItem() {
for (let i = 0; i < this.products.length; i++) {
this.scraperService.scrapSingle(this.products[i].url).subscribe(
res => {
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = this.products[i];
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
}
);
}
console.log(this.products.length);
}
But how to wait for subscribe before moving to next index in the loop?
Just splice the p_item into your array at the required index given i.
For example instead of doing,
this.processedItems.push(p_item);
do this,
this.processedItems.splice(p_item, 0, i);
That solves your problem :)
Use promises instead of rx.js subscriptions via using toPromise method. You might need to map the res to json. res.map(item => item.json());
products: any;
processedItems: Array < any > =[];
private _processItem() {
this.products.array.forEach(async (element) => {
const res = await this.scraperService.scrapSingle(element.url).toPromise();
if (res.status.http_code === 200) {
const properties = this.scraperService.processSingleProduct(res.contents);
const p_item = {};
p_item['info'] = element
p_item['properties'] = properties;
this.processedItems.push(p_item);
}
console.log(res);
});
console.log(this.products.length);
}

Too tidious hooks when querying in REST. Any ideas?

I've just started using feathers to build REST server. I need your help for querying tips. Document says
When used via REST URLs all query values are strings. Depending on the service the values in params.query might have to be converted to the right type in a before hook. (https://docs.feathersjs.com/api/databases/querying.html)
, which puzzles me. find({query: {value: 1} }) does mean value === "1" not value === 1 ? Here is example client side code which puzzles me:
const feathers = require('#feathersjs/feathers')
const fetch = require('node-fetch')
const restCli = require('#feathersjs/rest-client')
const rest = restCli('http://localhost:8888')
const app = feathers().configure(rest.fetch(fetch))
async function main () {
const Items = app.service('myitems')
await Items.create( {name:'one', value:1} )
//works fine. returns [ { name: 'one', value: 1, id: 0 } ]
console.log(await Items.find({query:{ name:"one" }}))
//wow! no data returned. []
console.log(await Items.find({query:{ value:1 }})) // []
}
main()
Server side code is here:
const express = require('#feathersjs/express')
const feathers = require('#feathersjs/feathers')
const memory = require('feathers-memory')
const app = express(feathers())
.configure(express.rest())
.use(express.json())
.use(express.errorHandler())
.use('myitems', memory())
app.listen(8888)
.on('listening',()=>console.log('listen on 8888'))
I've made hooks, which works all fine but it is too tidious and I think I missed something. Any ideas?
Hook code:
app.service('myitems').hooks({
before: { find: async (context) => {
const value = context.params.query.value
if (value) context.params.query.value = parseInt(value)
return context
}
}
})
This behaviour depends on the database and ORM you are using. Some that have a schema (like feathers-mongoose, feathers-sequelize and feathers-knex), will convert values like that automatically.
Feathers itself does not know about your data format and most adapters (like the feathers-memory you are using here) do a strict comparison so they will have to be converted. The usual way to deal with this is to create some reusable hooks (instead of one for each field) like this:
const queryToNumber = (...fields) => {
return context => {
const { params: { query = {} } } = context;
fields.forEach(field => {
const value = query[field];
if(value) {
query[field] = parseInt(value, 10)
}
});
}
}
app.service('myitems').hooks({
before: {
find: [
queryToNumber('age', 'value')
]
}
});
Or using something like JSON schema e.g. through the validateSchema common hook.

Wait for fetching data from Firebase before return

I have the following code:
UPDATE:
const showEvent = (eventLink) => {
let {events
} = database
let staffMembers = ""
let scenesList = ""
const staffMembersContainer = $('.staff-members')
const scenesContainer = $('.scenes')
const eventsGrid = $('#events-grid')
const eventHeader = $('#events-grid h2')
const eventKey = eventLink.getAttribute('data-key')
const {
name,
staff,
scenes
} = events[eventKey]
eventHeader.innerText = name
eventsGrid.classList.toggle("hidden")
Object.keys(staff).forEach(role => {
const staffMember = staff[role]
staffMembers += Staff(role, staffMember)
})
staffMembersContainer.innerHTML = staffMembers
Object.keys(scenes).forEach(scene => {
scenesList += Scene(scenes[scene])
})
scenesContainer.innerHTML = scenesList
}
const Staff = (role, staffMember) => {
const {
name
} = database.profiles[staffMember[0]]
return `
<li>
<p>${role}:</p>
<p>${name}</p>
</li>
`
}
const Scene = (id) => {
let promises = []
const {
name,
concerts
} = database.scenes[id]
let concertList = ""
concerts.forEach(concert => {
promises.push(
Concert(concert).then(bandName => {
concertList += `<li><p>${bandName}</p></li>`
})
)
})
return Promise.all(promises).then(() => {
return `
<li class="scene">
<p>Scene ${name}:</p>
<ul>
${concertList}
</ul>
</li>
`
})
}
const Concert = (id) => {
const bandId = database.concerts[id].band
return firebase.database().ref(`/bands/${bandId}/name`).once('value').then(snap => {
return snap.val()
})
}
So I would like to generate two lists, one containing the Staff members, the other one is containing lists of scenes, where scenes themselves are lists of Band names. I only could get plain HTML elements until I found out, that I should probably wait until the data is fetched from Firebase. As this is my first try with promises, the code is a bit messy, and probably is broken on several points.
If someone would have the time to help, I would extremely appreciate it!
Thanks