Render images from Entries in Contenful + Angular app - javascript

The issues:
How to I access the includes array so I can get the image url to render the image? (or how to I get the images to render in general)
Why is are my description fields not rendering?
So I have a contentful service that gets all the entries as such:
//get all exhibits
getExhibits(query?: object): Promise<Entry<any>[]> {
return this.cdaClient.getEntries(Object.assign({
include : 2,
content_type: CONFIG.contentTypeIds.exhibit
}, query))
.then(res => res.items);
}
The above function is called in my Gallery component as such:
ngOnInit() {
this.contentfulService.getExhibits()
.then(exhibits => this.exhibits = exhibits);
}
And the data is rendered in the corresponding HTML as such:
<section class="gallery__section" [class.menu--open]="menu.isMenuClosed" *ngFor="let exhibit of exhibits">
<figure>
<img src="{{ exhibit.fields.file.url }}" alt="">
<!-- HOW DO I GET THE IMG URL -->
</figure>
<div class="gallery__text">
<h2 class="gallery__heading">Gallery</h2>
<p class="gallery__title">{{ exhibit.fields.title }}</p>
<h3 class="gallery__artist">{{ exhibit.fields.artist }}</h3>
<p class="gallery_onview">On View</p>
<p class="gallery__dates">{{ exhibit.fields.date }}</p>
<p class="gallery__description" *ngIf="exhibit.fields.description.content[0].content[0].value">{{ exhibit.fields.description.content[0].content[0].value }}</p>
</div>
</section>
Bellow is the JSON of one item the items array:
And here the image that is supposed be part of the above item, but is placed in a different array called includes:
Below is the console.log output of one exhibit:

You don't need to access the includes array. The Contentful SDK will automatically resolve the fields that contain a reference.
For your image issue, I think you're missing the field name for your file field: exhibit.fields.YOUR_FIELD_NAME.fields.file.url
For your description field, I would recommend using ngx-contentful-rich-text to parse the rich text into HTML.

Related

Is there a method to implement through data attributes in JavaScript?

I want implement the card content in the card when expanded, I have used the help of JavaScript to implement the title, image, description ,I have used 'data-title' and 'data-type' for displaying title and image respectively which are by the working fine and when I try to implement card description by using data-desc attribute , it is displaying 'undefined'.
Anyone please help me with my code.
My code link: https://codepen.io/Avatar_73/pen/ExyNdMK
const getCardContent = (title, type, desc) => {
return `
<div class="card-content">
<h2>${title}</h2>
<img src="./assets/${type}.png" alt="${title}">
<p>${desc}</p>
</div>
`;
}
<div class="cards">
<div class="card" data-type="html" data-desc="I am HTML">
<h2>HTML5</h2>
</div>
</div>
On line 115, you forgot to pass the desc to your getCardContent function
Change to:
const content = getCardContent(card.textContent, card.dataset.type, card.dataset.desc)
Change your calling method signature from
getCardContent(card.textContent, card.dataset.type)
to
getCardContent(card.textContent, card.dataset.type, card.dataset.desc)
you are not passing the third parameter(card.dataset.desc) in the method thus it is rendering the value as undefined.

retrieving images from data return in vuejs

im trying to display som images in my code , already stored in my data in this way:
<div >
<tr v-for='(ships,index) in destroyedShipBox' :key='index'>
<td>{{ships}}</td>
<div v-for='(links,index1) in destroyedShipBoximages' :key='index1'>
{{links.type==ships?links.src:''}}
</div>
</tr>
</div>
where my data stores this arrays of objects:
data() {
return {
destroyedShipBox:['PatrolBoat','Destroyer'],
destroyedShipBoximages:[
{type:'PatrolBoat',src:require('../assets/patrolBoatHorizontalView.png')},
{type:'Submarine',src:require('../assets/submarineHorizontalView.png')},
{type:'BattleShip',src:require('../assets/battleshipHorizontalView.png')},
{type:'Carrier',src:require('../assets/carrierHorizontalView.png')},
{type:'Destroyer',src:require('../assets/destroyerHorizontalView.png')},
],
}
the destroyedShipBox gets fill automatically with some JSON already fetched then destroyedShipBoximages is just a collection of all type of ships in game as well as a image of its according to its type.
Thus my logic in the html template wants to set an image attuning with the kind of ships i already got in the destroyedShipBox array , but the the final result is this
PatrolBoat /img/patrolBoatHorizontalView.63b25d8d.png----->should be an image instead of this
Destroyer /img/destroyerHorizontalView.396ed25f.png ----->should be an image instead of this
simply the image don't appear...
Any advice about how to solve this problem...
thanks in advance!!!!
you can also ease up your template logic and have only one if condition if there is a 1:1 relation between ships and their images with the following computed property:
computed: {
shipsWithImages() {
return this.destroyedShipBoximages.filter((value) => {
if(this.destroyedShipBox.includes(value.type)) {
return value;
}
})
},
}
Cheers,
ewatch
You should assign links.src to src attribute of img tag like this:
<div>
<tr v-for='(ships,index) in destroyedShipBox' :key='index'>
<td>{{ships}}</td>
<td>
<div v-for='(links,index1) in destroyedShipBoximages' :key='index1'>
<img :src="links.src" v-if="links.type==ships"/>
</div>
</td>
</tr>
</div>

Show Object data when hovering over image

I have multiple objects like below. I want to display for each item an Image specific to its type and when hovering over it, it should display its name and dmg for example. The hovering effect should be like it is in facebook when you mouseover a profile.
How do I do that and how do I save the object data in the image? Can I even do that with vanila javascript? If not what should I use these type of data binding?
let item = {
name: "itemName",
type: "weapon",
dmg: 4
}
Inventory.js pastebin
index.html
<div class="inventory" id="inventory">
<div class="active-items" id="active-items">
<h3 class="inventory-h3">Active Items</h3>
</div>
<div class="bag-items" id="bag-items">
<h3 class="inventory-h3">Bag</h3>
</div>
</div>
EDIT:
When someone picks up an item the inventory ui is refreshed and an item is added but I want the item to contain the object data. I don't know how to accomplish this.
<img id="id" src="/src">
<div id="div_to_display_image_info"></div>
<script>
function(){
let item = {
name: "itemName",
type: "weapon",
dmg: 4
}
var img=document.getElementById('id')
img.addEventListener('onmouseover', ()=>{
document.getElementById("div_to_display_image_info").innerHTML = `dmg - ${item.dmg} name-${item.name}`
})
}
</script>

Iterating over keys instead of values Vue app

I'm trying to select the values for three keys from my api with axios.
Each time I make a request I'm displaying the values four times for each key. I dropped a key from my data models and I re tested. When I did that my request displayed three times instead of four. Meaning I'm iterating over the keys instead of the values.
How Can I change this code to display only the values of each key? I am using nuxt django and axios.
This is the json data axios returns.
{"id":1,"balance":10.0,"exposure":7.0,"free_funds":80.0}
How do I just get the values only for each paragraph tag instead of the values for each paragraph tag 4 times?
<template>
<div class="container">
<h2>Current Balance</h2>
<ul class="trendings">
<li v-for="result in results" :key="result">
<p>{{ results.balance }} balance</p>
<p>{{ results.free_funds }} free_funds</p>
<p>{{ results.exposure }} exposure</p>
</li>
</ul>
</div>
</template>
<script>
import axios from "axios";
export default {
asyncData() {
return axios.get("http://localhost:8000/api/balance/1").then(res => {
return { results: res.data };
});
}
};
</script>
If the JSON response looks exactly like this:
{"id":1,"balance":10.0,"exposure":7.0,"free_funds":80.0}
Then you don't even need the v-for because there is only one thing to iterate over.
If you want a v-for, force the data to come back as an array by wrapping it so that it would be this:
[ {"id":1,"balance":10.0,"exposure":7.0,"free_funds":80.0} ]
So:
return { results: [res.data] };
See the docs
<li v-for="(result, key) in results" :key="result">
<p>{{ result }} {{ key }}</p>
</li>

How do I pass the current item in a for loop to a method in vue.js 2?

I am building (as an exercise) a shopping cart in vue.js 2. I have my shop items and order items stored in my vue data array and a button rendered in a for loop for each shop item to add the item to the order (ex. push).
Here is the section of code that houses my list of items from my shop array in my vue data:
<fieldset>
<legend>Shop</legend>
<section v-if="shop">
<article v-for="(item, index) in shop">
<header><h1>{{ item.title }}</h1></header>
<p>{{ item.description }}</p>
<footer>
<ul>
<li>${{item.price}}</li>
<!-- find a way to set input name -->
<li><label>Quantity <input type="number" name=""></label></li>
<li><button v-on:click="addItemToOrder($event)">Add to Order</button></li>
</ul>
</footer>
</article>
</section>
<p v-else>No Items to Display</p>
</fieldset>
here is my vue element:
new Vue({
el: '#my-order',
data:{
'shop':[
{
'title':'Website Content',
'description':"Order your Website content by the page. Our search-engine-optimized web content puts you ahead of the competition. 250 words.",
'price':25,
'sku':'web001'
},
{
'title':'Blog Post',
'description':"We write blog posts that position your website as a go-to resource for expert knowlegde.",
'price':50,
'sku':'blog001'
},
{
'title':'Twitter Post'
},
{
'title':'Product Description'
}
],
'customizations':null,
'order':{
'items':null,
'total':null
},
'customer':null,
'payment':null
},
methods:{
addItemToOrder: function(){
/* Here is where I need to append the item to the cart */
}
}
})
How do I pass the item in the for loop to the order (eg: append it to order.items)?
You just need to pass the item in as a parameter to the function.
v-on:click="addItemToOrder(item)"
Then you can use it your Vue component
addItemToOrder: function(item){
this.order.items.push(item);
}
Make sure you initialize order.items to an empty array inside your components data so that you can push to it.
'order':{
'items': [],
'total': 0
},
In general, it is a good idea to initialize your data to the correct data type if you know what it will be.
I realise this is a bit late however in case anyone else happens across this thread...
You need to pass in the event as well as the item
in your vue code
someMethod : function(e, item){}
in your html
<a v-on:click="someMethod($event, $data)"></a>

Categories