Unable to get image using background property in React - html

I am trying to make cards from an array of objects containing ids and URL (relative paths ) to my images. But when I try to use mapping to return arrays and use background CSS property to set images I am unable to do it. Below is the code
import React from "react";
import { useState } from "react";
import { Fragment } from "react";
// import { Link } from "react-router-dom";
import styles from "../Styles/Services.module.scss";
const Services = () => {
const [pic, setPic] = useState(1);
const list = [
{ id: 1, url: "../Images/mentorship.jpg" },
{ id: 2, url: "../Images/entertainment.jpg" },
{ id: 3, url: "../Images/support.jpg" },
{ id: 4, url: "../Images/opportunity.jpg" },
{ id: 5, url: "../Images/counselling.jpg" },
];
// const clickHandler = (e) => {
// console.log(e.target.value);
// setPic(e.target.value);
// };
return (
<Fragment>
<section
className="bg-light p-5 text-dark"
style={{ fontFamily: "Lato" }}
>
<div className="container py-5 ">
<div className="display-2 text-center">Our Services</div>
<div className={`${styles.bodyCard}`}>
<div className={`${styles.options}`}>
{list.map((x) => {
var a = x.url;
return (
<div
key={x.id}
value={x.id}
className={`${styles.option} ${
pic === x.id ? styles.active : ""
}`}
onClick={() => setPic(x.id)}
style={{
background: `url(${
require(a).default
})`,
backgroundSize: "auto 100%",
backgroundPosition: "center",
}}
>
<div className={`${styles.shadow}`}></div>
<div className={`${styles.label}`}>
<div className={`${styles.icon}`}>
<i className="fas fa-walking"></i>
</div>
<div className={`${styles.info}`}>
<div className={`${styles.main}`}>Blonkisoaz</div>
<div className={`${styles.sub}`}>
Omuke trughte a otufta
</div>
</div>
</div>
</div>
);
})}
;
</div>
</div>
</div>
</section>
</Fragment>
);
};
export default Services;
I am unable to display images at code background
background: `url(${require(x.url).default})
But When I use this it works.
background: `url(${require("../Images/mentorship.jpg").default})
It gives this error in React
enter image description here
**Kindly do not make it a duplicate as I have checked other similar questions as well and have found no answer there. Thanks **

import React from "react";
import { useState } from "react";
import { Fragment } from "react";
// import { Link } from "react-router-dom";
import styles from "../Styles/Services.module.scss";
import image1 from "../Images/mentorship.jpg";
import image2 from "../Images/entertainment.jpg";
const Services = () => {
const [pic, setPic] = useState(1);
const list = [
{ id: 1, url: image1 },
{ id: 2, url: image2 },
];
// const clickHandler = (e) => {
// console.log(e.target.value);
// setPic(e.target.value);
// };
return (
<Fragment>
<section
className="bg-light p-5 text-dark"
style={{ fontFamily: "Lato" }}
>
<div className="container py-5 ">
<div className="display-2 text-center">Our Services</div>
<div className={`${styles.bodyCard}`}>
<div className={`${styles.options}`}>
{list.map((x) => {
var a = x.url;
return (
<div
key={x.id}
value={x.id}
className={`${styles.option} ${
pic === x.id ? styles.active : ""
}`}
onClick={() => setPic(x.id)}
style={{
background: `url(${a})`,
backgroundSize: "auto 100%",
backgroundPosition: "center",
}}
>
<div className={`${styles.shadow}`}></div>
<div className={`${styles.label}`}>
<div className={`${styles.icon}`}>
<i className="fas fa-walking"></i>
</div>
<div className={`${styles.info}`}>
<div className={`${styles.main}`}>Blonkisoaz</div>
<div className={`${styles.sub}`}>
Omuke trughte a otufta
</div>
</div>
</div>
</div>
);
})}
;
</div>
</div>
</div>
</section>
</Fragment>
);
};
export default Services;

As mentioned in the answerer above by https://stackoverflow.com/users/12902108/samira , it will work, just set style as style={{ background: `url(${photo})` }} assuming image is imported as photo .

Related

Image doesn't show up in react render

I want to add an image in a tinder-clone app. I followed the mern stack tutorial on the clever programmer youtube channel. Unfortunately, the image didn't show up in the browser.
This is my code:
import React, { useState } from 'react';
import "./TinderCards.css";
import TinderCard from 'react-tinder-card';
function TinderCards() {
const [people, setPeople] = useState([
{
name: 'Elon Musk',
url: "https://upload.wikimedia.org/wikipedia/commons/3/34/Elon_Musk_Royal_Society_%28crop2%29.jpg",
},
]);
const swiped =(direction, nameToDelete) => {
console.log("removing: " + nameToDelete);
};
const outOfFrame = (name) => {
console.log(name + "left the screen!");
};
return (
<div className="tinderCards">
<div className="tinderCards__cardContainer">
{people.map(person => (
<TinderCard
className="swipe"
key={person.name}
preventSwipe= {["up", "down"]}
onSwipe={(dir) => swiped(dir, person.name)}
onCardLeftScreen={() => outOfFrame(person.name)}
>
<div
style={{ backgroundImage: 'url(${person.url})' }}
className="card"
>
<h3>{person.name}</h3>
</div>
</TinderCard>
))}
</div>
</div>
);
}
export default TinderCards
And this is what I see in the browser:
tinder clone

Vue Router not working properly and adds a #

I have a main app page component with a search bar. The Search results that come back is in cards And I am looking to set up a "Click here to view more detail" that would be placed in each card. And it would link to the Details page of the one result clicked. How do I link these components on Vue and if the id could be passed? I am hoping that upon click of the button the component renders on the same page and not a new tab.
Once I click on "click here" It updates the link to http://localhost:8081/#/{name:'Details',%20params:%20{id:%20result._gddid}}
and
I get an [Vue warn]: Property or method "results" is not defined on the instance but referenced during render.
Thank you!
app.vue
<template>
<div id="app">
<Header/>
<SearchForm v-on:search="search"/>
<SearchResults
v-if="results.length > 0"
v-bind:results="results"
v-bind:reformattedSearchString="reformattedSearchString"/>
<Details
v-bind:results="results"
/>
<Pagination
v-if="results.length > 0"
v-bind:prevPageToken="api.prevPageToken"
v-bind:next_page="api.scrollId"
v-on:prev-page="prevPage"
v-on:next-page="nextPage"
/>
</div>
</template>
<script>
import Header from './components/layout/Header';
import SearchForm from './components/SearchForm';
import SearchResults from './components/SearchResults';
import Details from './components/Details'
import Pagination from './components/Pagination';
import axios from 'axios';
export default {
name: 'app',
components: {
Header,
SearchForm,
SearchResults,
Details,
Pagination
},
data() {
return {
results: [],
reformattedSearchString: '',
api: {
baseUrl: 'https://test.org/api/v1/articles?',
max: 25,
q: '',
prevPageToken: '',
scrollId: ''
}
};
},
methods: {
search(searchParams) {
this.reformattedSearchString = searchParams.join(' ');
this.api.q = searchParams.join('+');
const { baseUrl, q, max} = this.api;
const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&recent&max=${max}&full_results`;
this.getData(apiUrl);
},
prevPage() {
const { baseUrl, q, max, prevPageToken } = this.api;
const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&max=${max}&pageToken=${prevPageToken}`;
this.getData(apiUrl);
},
nextPage() {
const { baseUrl, q, max,scrollId } = this.api;
const apiUrl = `${baseUrl}&term=${q}&title_like=${q}&max=${max}&recent&full_results&scroll_id=${scrollId}`;
this.getData(apiUrl);
},
getData(apiUrl) {
axios
.get(apiUrl)
.then(res => {
this.results = res.data.success.data;
this.api.prevPageToken = res.data.success.data.prevPageToken;
this.api.next_page = res.data.scrollId;
})
.catch(error => console.log(error))
}
}
};
</script>
SearchResults.vue
<template>
<div class="container mb-3">
<div class="d-flex mb-3">
<div class="mr-auto">
<h3>Search Results for "{{ reformattedSearchString }}"</h3>
</div>
<div class="btn-group ml-auto" role="group">
<button
#click="changeDisplayMode('grid')"
type="button"
class="btn btn-outline-secondary"
v-bind:class="{ active: displayMode === 'grid' }"
>
<i class="fas fa-th"></i>
</button>
<button
#click="changeDisplayMode('list')"
type="button"
class="btn btn-outline-secondary"
v-bind:class="{ active: displayMode === 'list' }"
>
<i class="fas fa-list"></i>
</button>
</div>
</div>
<div class="card-columns" v-if="displayMode === 'grid'">
<div class="card" v-bind:key="result._gddid" v-for="result in results">
<ArticleGridItem v-bind:result="result"/>
</div>
</div>
<div v-else>
<div class="card mb-2" v-bind:key="result._gddid" v-for="result in results">
<ArticleListItem v-bind:result="result"/>
</div>
</div>
<div class="card mb-2" v-bind:key="result._gddid" v-for="result in results">
<Details v-bind:result="result"/>
</div>
</div>
</template>
<script>
import ArticleListItem from './ArticleListItem';
import ArticleGridItem from './ArticleGridItem';
import Details from './Details';
export default {
name: 'SearchResults',
components: {
ArticleListItem,
ArticleGridItem,
Details,
},
data() {
return {
title: 'Search Results',
displayMode: 'grid'
};
},
methods: {
changeDisplayMode(displayMode) {
this.displayMode = displayMode;
}
},
props: ['results', 'reformattedSearchString']
};
</script>
<style scoped>
button:focus {
box-shadow: none !important;
}
</style>
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router';
import moment from 'moment'
Vue.config.productionTip = false
Vue.filter('formatDate', function (value) {
if (!value) return ''
return moment(value.toString()).format('MM/DD/YYYY hh:mm')
})
Vue.use(VueRouter)
import Details from './components/Details';
const router = new VueRouter({
routes: [
{
path: '/Details/:id',
name: 'Details',
component: Details
}
]
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
ArticleListItem.vue
<template>
<div>
<div class="card-body">
<h6 class="card-text">{{ result.title }}</h6>
<p class="card-subtitle mb-2 text-muted"
>{{ result.publisher }} | {{ result.journal }} | {{ result.year }}</p>
<a :href="'https://test.org/api/articles?docid=' + result._gddid" target="_blank">
<i class="fa fa-download" alt="Download"> </i>
</a>
<router-link dark to="{name:'Details', params: {id: result._gddid}}">
Click here for more Details
</router-link>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'ArticleListItem',
props: ['result'],
}
</script>
Details.vue
<template>
<div class="Details">
<div class="container">
<div class="row">
<div class="col-md-12" v-for="result in results" :key="result._gddid">
<div v-if="id == result._gddid">
<h1>{{result.title}}</h1>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Details',
props: ['result'],
};
</script>
Once I click on "click here" It updates the link to http://localhost:8081/#/{name:'Details',%20params:%20{id:%20result._gddid}}
Glancing over the code it appears that within ArticleListItem.vue the router-link's to attr isn't bound so it's treated as a string.
Currently: to="{name:'Details', params: {id: result._gddid}}"
Try: :to="{name:'Details', params: {id: result._gddid}}" so it's passed as an object.
I get an [Vue warn]: Property or method "results" is not defined on the instance but referenced during render.
Within Details.vue you have props: ['result'], but in the v-for it looks for results which isn't defined within data() nor within props.
As for the # appearing, vue-router's default mode is hash, if you're not wanting to use # you can set it to history via:
const router = new VueRouter({
mode: 'history',
routes: [...]
})
But beware you'll need a server running to handle the routing; You can find more info at https://router.vuejs.org/guide/essentials/history-mode.html#html5-history-mode

TypeError: links.map is not a function React

I'm working with reactjs typescript and cannot seem to prevent this error when trying to display JSON data from the server:
import React, { useRef, useState } from "react";
import useHttp from "../hooks/usehttp";
const HomePage: React.FC = () => {
const [links, setLinks] = useState([]);
const ref = useRef<HTMLInputElement>(null);
const { request } = useHttp();
const pressHandler = async (event: React.KeyboardEvent) => {
if (event.key === "Enter") {
try {
const data = await request(
"http://localhost:5000/api/link/generate-guest",
"POST",
{ from: ref.current!.value },
{}
);
alert(data.message);
console.log(data.link.to); // the link => localhost:5000/jshdadsa
setLinks(data.link.to);
console.log(links); // shows undefined ?????
} catch (error) {
alert(error);
}
}
};
return (
<>
<div className="row">
<div className="col s8 offset-s2" style={{ paddingTop: "2rem" }}>
<div className="input-field">
<input
placeholder="Enter link"
id="link"
type="text"
ref={ref}
onKeyPress={pressHandler}
/>
<label htmlFor="link">Enter link</label>
</div>
<div>
{ {links.map((link: any) => {
return (
<ul className="collection with-header">
<li className="collection-item">{link}</li>
</ul>
);
})} }
</div>
</div>
</div>
</>
);
};
export default HomePage;
Not sure what i am missing.
Use this code in order to update the array of link in your example:
setLinks([...links, data.link.to])

Conditionally render lyrics based off track index?

I'm trying to create a track list. I want to render the track lyrics based off of the track name that was clicked on for the specified id. However, I'm having some trouble doing so.
The data is being fetched from MySQL.
Here is my code:
Model:
var db = require("../dbconnection");
var music = {
insertmusicTracks: function(data, callback) {
db.query(
"insert music_tracks set track_music_id=?, track_user_id=?, trackName=?, trackLyrics=?",
[data.albumId, data.userId, data.songName, data.songLyrics],
callback
);
},
selectmusicTracks: function(data, callback) {
db.query(
"select mo.track_music_id, mo.trackName, mo.trackLyrics, mt.authorName, mt.trackTitle, mt.trackYear, mt.trackcoverImg from music_tracks mo left join music_topics mt on mt.music_id=mo.track_music_id where mo.track_music_id=?",
[data.trackmusicId],
callback
);
}
};
module.exports = music;
View:
import React from "react";
import { Link } from "react-router-dom";
import { Modal, Button } from "react-bootstrap";
import Headericons from "../common/header-icons";
import Header from "../common/header";
import Footer from "../common/footer";
import Addtracklist from "../components/addmusictrack";
import dataTip from "data-tip";
import appController from "../../controllers/appController";
import musicService from "../../services/musicService";
class Musictracks extends React.Component {
constructor(props) {
super(props);
this.state = {
userId: "",
isAdmin: false,
albumName: "",
musicId: this.props.match.params.musicid,
trackData: []
};
}
handleClose = () => {
this.setState({ show: false });
};
handleShow = () => {
this.setState({ show: true });
};
selectTracks = async () => {
const selectmusicTracks = await musicService.selectmusicTracks({
trackmusicId: this.props.match.params.musicid
});
this.setState({
trackData: selectmusicTracks
});
console.log(this.state);
};
showLyrics = async trackId => {
this.setState({
lyricId: trackId
});
console.log(this.state);
};
async componentDidMount() {
if (appController.isAdmin().role_id === 3) {
await this.setState({
userId: appController.isAdmin().userID,
isAdmin: true
});
}
this.setState({
albumName: this.props.match.params.title
});
await this.selectTracks();
await this.showLyrics();
}
render() {
return (
<div className="fluid-container">
<Headericons />
<Header />
<div className="container" id="musictrackContainer">
<h1>{appController.removeHyphen(this.state.albumName)}</h1>
<div className="row">
<Link className="btn btn-primary" id="previouspage" to="/music">
← Go Back
</Link>
</div>
{this.state.isAdmin === true ? (
<div className="row" id="superAdmin">
<div className="col-md-12">
<i
className="far fa-plus-square fa-2x"
onClick={this.handleShow}
/>
</div>
<div className="static-modal">
<Modal show={this.state.show} onHide={this.handleClose}>
<Modal.Header closeButton>
<Modal.Title>Add Track</Modal.Title>
</Modal.Header>
<Modal.Body>
<Addtracklist
albumId={this.state.musicId}
userId={this.state.userId}
closeModal={this.handleClose}
/>
</Modal.Body>
</Modal>
</div>
</div>
) : null}
<div className="row">
<div className="col-md-4">
<div className="trackContainer">
<ol>
{this.state.trackData.map((rows, index) => (
<div
className="trackName data-tip-right"
data-tip={"View " + rows.trackName}
key={rows.trackName + "-" + rows.track_music_id}
onClick={e => this.showLyrics(index)}
>
<li tabIndex={index}>
{index + 1 + ". " + rows.trackName}
<i className="fas fa-arrow-right" />
</li>
</div>
))}
</ol>
</div>
</div>
<div className="col-md-8">
// This is where I'm stuck I'm not sure how I can render lyrics based off of the track name.
{this.state.trackData.map((row, index) =>
this.state.lyricId === index ? (
<div className="trackLyrics">{row.trackLyrics}</div>
) : null
)}
</div>
</div>
</div>
<Footer />
</div>
);
}
}
export default Musictracks;
The above snippet is my attempt to try and render the lyrics based off of track name that the user clicks on.
Nevermind I figured it out. I made a small error in my code. I simply had to replace row.index with index and it worked. Edited my question.

table vue.js with json on laravel

I am trying to show result from json to table with vue.js
i have no result this is the script:
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="title">Progress Queue's details Live</h4>
</div>
<div class="card-content table-responsive table-full-width">
<el-table :data="tableData2">
<el-table-column label="Name" property="name"></el-table-column>
<el-table-column class="danger" label="Numbers" property="numbers"></el-table-column>
</el-table>
</div>
</div>
</div>
<script>
import ChartCard from 'src/components/UIComponents/Cards/ChartCard.vue'
Vue.use(Table)
Vue.use(TableColumn)
const WorldMap = () => ({
component: import('./../Maps/WorldMap.vue'),
loading: Loading,
delay: 200
})
import axios from 'axios';
import Vue from 'vue'
import {Table, TableColumn} from 'element-ui'
Vue.use(Table)
Vue.use(TableColumn)
// Vue.use(tableRowClassName)
import vSelect from 'vue-select';
//Vue.component('v-select', VueSelect.VueSelect)
export default {
components: {
vSelect,
StatsCard
},
data () {
return {
tableData2: [],
},
mounted() {
axios.get("/statcard").then(response => {
this.tableData2.push({
name: response.data.queue,
numbers: reponse.data.queue_count
});
});
}
}
i recieve no data
the result of the json is :
{"queue_count":"4","queue":"OP_AD_WIN_HARDWARE"},{"queue_count":"35","queue":"OPBO_WIN_Fiber_pend_i"},{"queue_count":"5","queue":"OP_AD_WIN_RELOCATION"},{"queue_count":"44","queue":"OPBO_WIN_Act_pend_i"}]}
Remove mounted from data.
Don't add plugins multiple times.
The element documentation says, that prop is correct, not property.
Work on your line indentation.
<template>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="title">Progress Queue's details Live</h4>
</div>
<div class="card-content table-responsive table-full-width">
<el-table :data="tableData2">
<el-table-column label="Name" prop="queue_count"></el-table-column>
<el-table-column class="danger" label="Numbers" prop="queue"></el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
import Vue from 'vue';
import vSelect from 'vue-select';
import axios from 'axios';
import { Table, TableColumn } from 'element-ui';
import ChartCard from 'src/components/UIComponents/Cards/ChartCard.vue';
Vue.use(Table);
Vue.use(TableColumn);
const WorldMap = () => ({
component: import('./../Maps/WorldMap.vue'),
loading: Loading,
delay: 200
});
export default {
components: {
vSelect,
StatsCard
},
data() {
return {
tableData2: []
};
},
mounted() {
axios.get('/statcard').then(response => {
this.tableData2 = response.data.queue_progress;
});
}
};
</script>