How to add src path into vue component from json file - javascript

How to render images, if i get path from json file. Default i use require('../assets/img/item-image.png'). But i have no idea, how use it in this case
Component:
<div v-for="(item, index) in items">
<img :src="item.src">
</div>
<script>
import axios from 'axios'
export default {
name: 'componentName',
data () {
return {
items: null
}
},
mounted () {
axios
.get('./test.json')
.then(response => (this.items = response.data))
}
}
</script>
JSON file:
[
{
"id": 1,
"title": "item title",
"src": "../assets/img/item-image.png",
"alt": "item-image",
"text": "item body"
}
]

You need to keep using require() in order to let Webpack know to include your images when bundling.
Because Webpack bundles at compile time and your images are only known at runtime, this is best done by keeping part of the path static so Webpack can optimistically include the right files.
For example, if all your images are under ../assets/img, the best option would look like this
async mounted () {
const pathRegex = /^\.\.\/assets\/img\//
const { data } = await axios.get("./test.json")
this.items = data.map(item => ({
...item,
src: require(`../assets/img/${item.src.replace(pathRegex, "")}`)
}))
}
Webpack will then bundle every file under ../assets/img and at runtime, will be able to resolve the paths you supply.
See https://webpack.js.org/guides/dependency-management/#require-with-expression

You must add require
<img :src="require(item.src)">

This was how I solved it. I kept getting an error when using the regex above to add require to the src attribute in the json. This is what I did instead and it worked for me.
I am using fetch() to read the json which I am watching with json-server. The json is basically an array (cokeImages) of objects when you use res.json() to convert it.
{
"cokeImages": [
{
"title": "Cocacola Life",
"description": "Lorem ipsum no sicut anon in aquila no ager. In homines ad majorem tempus avis, et cum in pecunia imoten tua",
"src": "../assets/cocacola-cans/cocacola-life.png",
"id": 1,
"name": "cocacola-life",
"nutrition": [
{ "title": "sodium", "value": "150 cl", "percent": "25%" },
{ "title": "Total Fats", "value": "0g", "percent" : "0%" },
{ "title": "sodium (mg)", "value": "40mg", "percent": "0%"},
{ "title": "potasium", "value": "4g", "percent": "0%" },
{ "title": "calcium", "value": "0g", "percent": "0%"}
]
},
{
"title": "Cocacola Zero",
"description": "Lorem ipsum no sicut anon in aquila no ager. In homines ad majorem tempus avis, et cum in pecunia imoten tua",
"src": "../assets/cocacola-cans/cocacola-zero.png",
"id": 2,
"name": "cocacola-zero",
... (and so on)...
as you can see, the name property in each object is also the name I used in each images src.
It is that name property I used in the map() method to attach require to each src.
mounted(){
fetch("http://localhost:3000/cokeImages")
.then(response => response.json())
.then(arrayOfOjects => {
console.log(arrayOfObjects)
this.cokeImages = data.map(eachObject => {
return {...eachObject, src: require(`../assets/cocacola-cans/${eachObject.name}.png`)}
})
console.log(this.cokeImages)
})
.catch(err => {
console.log(err.message)
})
}

Related

Looping through array, fetching tweets and returning new reversed array javascript react

UPDATE: I have deployed the site for more context you can view it here https://conundrum-quest-rw-rebuild-web.onrender.com/
the public repo is here
https://github.com/wispyco/conundrum-quest-rw-rebuild
Note: the data on the live site is different but the initial load is loading the hero's on the wrong cards, you can compare the quest with subsequent heros on the home page and the returned data from my function below, you can scroll down to see the rendered cards.
You can see that if you click on a card it shows the correct heros on the single page.
I have the following quests data structure that I am looping through in a separate function and running a fetch to request some profile images from twitter.
[
{
"__typename": "Quest",
"id": 5,
"name": "How do we solve mental health related issues?",
"userId": 17,
"heros": [
{
"__typename": "Hero",
"name": "Anders Kitson",
"twitter": "anderskitson"
},
{
"__typename": "Hero",
"name": "ders",
"twitter": "derz_O"
}
]
},
{
"__typename": "Quest",
"id": 6,
"name": "How do we create a world where North Korea participates and collaborates with the rest of the World?",
"userId": 17,
"heros": [
{
"__typename": "Hero",
"name": "Crypto Dude",
"twitter": "phunk2243"
}
]
}
]
Here is my custom hook
const twitter = useFetchTwitterMultipleQuests(quests)
export const useFetchTwitterMultipleQuests = (twitterProfileManyQuests) => {
const [twitter, setTwitter] = useState([])
useEffect(() => {
twitterProfileManyQuests.forEach(async (twitterProfileMany, i) => {
const woop = twitterProfileMany.heros.map(async (twitterProfile) => {
const test = fetch(
`${window.location.origin}/.redwood/functions/twitter`,
{
method: 'POST',
body: JSON.stringify({ twitter: twitterProfile.twitter }),
}
)
.then(function (response) {
// The response is a Response instance.
// You parse the data into a useable format using `.json()`
console.log('test')
return response.json()
})
.then(function (data) {
return data.data.resultAwaited.data
})
const go = await test
return go
})
const june = await Promise.all(woop)
setTwitter((prevState) => {
return [...prevState, june]
})
})
}, [twitterProfileManyQuests])
const reversedTwitter = twitter.reverse()
return reversedTwitter
}
The problem is the reversedTwitter or twitter variable in the end sometimes is in the correct reversed order and sometimes not reversed, and I can't figure out why.
This is the correct order result
[
[
{
"username": "anderskitson",
"profile_image_url": "https://pbs.twimg.com/profile_images/1428160652237889539/I7ZiM_g8_normal.jpg",
"name": "▲nders on a quest 🜸 to see myself 🪞",
"id": "4633808432"
},
{
"profile_image_url": "https://pbs.twimg.com/profile_images/1496985668043436033/NoyLrUys_normal.jpg",
"name": "ders.eth",
"id": "1389695824934834181",
"username": "derz_O"
}
],
[
{
"username": "phunk2243",
"profile_image_url": "https://pbs.twimg.com/profile_images/1536485988767350784/cfP_sPSC_normal.jpg",
"name": "9999999333 (🅱️uilding 35 Phunks) 🔜",
"id": "1355005208259133442"
}
]
]
This is the incorrect order result
[
[
{
"name": "9999999333 (🅱️uilding 35 Phunks) 🔜",
"profile_image_url": "https://pbs.twimg.com/profile_images/1536485988767350784/cfP_sPSC_normal.jpg",
"username": "phunk2243",
"id": "1355005208259133442"
}
],
[
{
"username": "anderskitson",
"profile_image_url": "https://pbs.twimg.com/profile_images/1428160652237889539/I7ZiM_g8_normal.jpg",
"name": "▲nders on a quest 🜸 to see myself 🪞",
"id": "4633808432"
},
{
"username": "derz_O",
"profile_image_url": "https://pbs.twimg.com/profile_images/1496985668043436033/NoyLrUys_normal.jpg",
"name": "ders.eth",
"id": "1389695824934834181"
}
]
]
The reason this matters is how I am rendering the data. I am rendering a Quest from the quests data, then mapping over the heros in a quest which correspond to the twitter profiles.
See Here
{quests.map((quest, i) => (
<QuestCard key={quest.id}>
<Link to={routes.quest({ id: quest.id })} key={quest.id}>
<div>
<h3>{truncate(quest.name)}</h3>
{quest.heros.map((hero, index) => (
<React.Fragment key={hero.id}>
{twitter.length > 0 && twitter[i] && (
<span>
{hero.name}
<p>{twitter[i][index]?.name}</p>
<img
key={i}
src={twitter[i][index]?.profile_image_url}
alt={twitter[i][index]?.name}
/>
</span>
)}
</React.Fragment>
))}
</div>
</Link>
<div className="clear" />
</QuestCard>
))}
Any help would be greatly appreciated, most of what I have done works, but after about three refreshes the ordering breaks. Thanks
Fixed by using a custom service and a custom sdl in redwood instead of using a function and having to create a custom hook for rendering. This was recommended by the RW team from this article
https://redwoodjs.com/docs/how-to/using-a-third-party-api
And you can see my changes here
https://github.com/wispyco/conundrum-quest-rw-rebuild/pull/8/commits/41637813dd50be70e2e89372606c08e39618fa07

Javascript/React code - control/page won't render in fileReader.onload

I have a react page and one of my inputs is a file upload. When loading, I want to read in the file (it's JSON) and then show the file as a tree to allow my users to select nodes (rules) to run against another dataset. BUT, when I pick the JSON file and the 'onload' event handler actually fires off, the page just stops rendering, I get a blank screen. I'm not sure why, I can't see any errors, but I AM IGNORANT with react and kinda new with javascript as well. So, this is quite likely just a dumb thing I'm doing. Can someone point me at what I'm doing wrong here?
handleRules(event) {
const ruleRdr = new FileReader();
ruleRdr.onload = async (e) => {
const rBuf = (e.target.result);
const rData = JSON.parse(new TextDecoder().decode(rBuf));
// the data is there, but it's not mapping into the tree...!?!?!?
const tree = {
name: "QA/QC Rules",
id: 1,
toggled: true,
children: rData.map((wFlow, index) => ({
name: wFlow.WorkflowName,
id: index,
children: wFlow.Rules.map((rule, idx) => ({
name: rule.RuleName,
id: idx
}))
}))
};
this.setState({ ruleData: rData, hasRules: true, treeData: tree });
}
ruleRdr.readAsArrayBuffer(event.target.files[0]);
}
EDIT #1: I don't think it's the code above now, I think it might be my tree library (react-treebeard) or my ignorance on how I'm using it. The code produces what I think is useable data, but it isn't rendering it out.
{
"name": "QA/QC Rules",
"id": 1,
"toggled": true,
"children": [
{
"name": "COMP",
"id": 0,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
},
{
"name": "PNLCOMP",
"id": 1,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
},
{
"name": "PNLTERM",
"id": 2,
"children": [
{
"name": "ParentMustHaveCat",
"id": 0
},
{
"name": "ParentMustHaveMfg",
"id": 1
},
{
"name": "ParentMustHaveFamily",
"id": 2
},
{
"name": "SymbolsMustHaveFamily",
"id": 3
}
]
}
]
}
I figured it out. I switched to MUI since it has more components that I will want to use anyway. I got a similar issue with it as well and realized that I have duplicate IDs between the parent and the children, and was creating a kind of lock when trying to compare parent and child IDs in the MUI library. Totally on me - I'm dumb.

Error using JSON object as property for Image source

so guys i have the path of images coming from a JSON File likes this
[
{
"name": "Cebola Roxa",
"price": 4,
"quantity": 0,
"path": "../assets/productsImages/purpleonion.png"
},
{
"name": "Cenoura",
"price": 4,
"quantity": 0,
"path": "../assets/productsImages/carrot.png"
},
]
The path for the images are correct, the problem is that when i try to use this path inside of o source using require it says Sintax Error
import products from '../assets/products.json'
const listProducts = products.map((product,index) => {
return( <Image source={require(product.path)} style={styles.imgProduct} />)
}
How can i load images using the path from a JSON file ?

How to read object URI (JSON file) from JSON file

I am able to read this JSON file but I am not able to read object URI JSON file. How can I use Object URI JSON File?
And this is the way I tried to read Uri JSON object
componentDidMount(){
const { match: { params } } = this.props;
axios.get(params.uri).then((res)=>{
const question = res.data[0]['uri'];
console.log(question);
this.setState({ question });
})
}
This is JSON file where Object URI contains a JSON file so how to read
[
{
"id": 59413,
"thumbnail": {
"id": "60255",
"title": "dornoch-castle-whisky-bar",
"alt": "dornoch-castle-whisky-bar",
"url": "https://media-magazine.trivago.com/wp-content/uploads/2019/01/23144800/dornoch-castle-whisky-bar.jpg",
"courtesy": "",
"position": "center"
},
"thumbnail_url": "https://media-magazine.trivago.com/wp-content/uploads/2019/01/23144800/dornoch-castle-whisky-bar.jpg",
"slug": "dornoch-castle-scotland-whisky",
"uri": "http://trivago-magazine-work-sample-server.s3-website.eu-central-1.amazonaws.com/dornoch-castle-scotland-whisky.json",
"title": "Dornoch Castle: A Whisky Tasting at One of the World's Most Popular Hotel Bars",
"card_title": "Whisky Tasting at Dornoch Castle in the Scottish Highlands",
"show_publish_date": false,
"date": "January 29th, 2019",
"newsletter_popup": false,
"newsletter_popup_header_image": false,
"taxonomies": {
"destinations": [
{
"name": "Europe",
"uri": "/destination/international/europe",
"slug": "europe",
"term_id": 1384
}
],
"themes": [],
"types": [
{
"name": "Nature",
"uri": "/type/nature",
"slug": "nature",
"term_id": 1380
}
]
},
"excerpt": "Dornoch Castle has amassed a whisky collection unlike most any other in the world. trivago Magazine Editor, Joe Baur, signs up for their whisky tasting. Video below."
},
Using the same way you extracted the first uri json data, fire another request to get the data from the second uri = res.data[0]['uri']
componentDidMount(){
const { match: { params } } = this.props;
axios.get(params.uri).then((res)=>{
const question = res.data[0]['uri'];
axios.get(question).then((qRes) => {
console.log(qRes); //will return the data from the second uri
})
console.log(question);
this.setState({ question });
})
}
I think this is just a normal JSON. You can get the file by reading direct to field url and thumnail_url
"url": "https://media-magazine.trivago.com/wp-content/uploads/2019/01/23144800/dornoch-castle-whisky-bar.jpg",
You can show this file by
<img src="https://media-magazine.trivago.com/wp-content/uploads/2019/01/23144800/dornoch-castle-whisky-bar.jpg" />

Nested forEach issue

I have two arrays of object, the first array (printers, around 80 elements) is made of the following type of objects:
[{
printerBrand: 'Mutoh',
printerModel: 'VJ 1204G',
headsBrand: 'Epson',
headType: '',
compatibilty: [
'EDX',
'DT8',
'DT8-Pro',
'ECH',
],
cartridges: [],
},
....
]
The second array (cardridges, around 500 elements) is made of the following type of objects:
[
{
"customData": {
"brand": {
"value": {
"type": "string",
"content": "ECH"
},
"key": "brand"
},
"printer": {
"value": {
"type": "string",
"content": "c4280"
},
"key": "printer"
}
},
"name": "DT8 XLXL",
"image": {
"id": "zLaDHrgbarhFSnXAK",
"url": "https://xxxxxxx.net/images/xxxxxx.jpg"
},
"brandId": "xxxxx",
"companyId": "xxxx",
"createdAt": "2018-03-26T14:39:47.326Z",
"updatedAt": "2018-04-09T14:31:38.169Z",
"points": 60,
"id": "dq2Zezwm4nHr8FhEN"
},
...
]
What I want to do first is to is to iterate through the first array and and then iterate for all the cardridge available: if a the value customData.brand.value of a cardridge is included inside the array 'compatibility' of a printer, then I have to add this cardridge object inside the cardridges array of this printer. I have tried but somehow the iteration doesn't take place correctly. This is what I tried:
printers.forEach((printerItem) => {
const printer = printerItem;
printer.compatibilty.forEach((compatibilityItem) => {
const compatibility = compatibilityItem;
cardridges.forEach((cartridge) => {
if (compatibility === cartridge.customData.brand.value.content) {
printer.cartridges.push(cartridge);
}
});
});
});
What am I doing wrong?
You're accessing the wrong property. It should be cartridge.customData.brandName.value.content, carefully note brandName.value rather than brand.value
Your issue is that you're accessing it by the wrong property - brand and not brandName.
Furthermore, if you're targeting everything but IE, you could simplify your nested for loops to utilize some fancy ES6 array methods.
printers.forEach((p) => {
p.cartridges.push(cartridges.filter((c) => {
const brandName = c.customData.brandName.value.content;
return p.compatibilty.includes(brandName);
}));
});

Categories