how to bind a value in require() Vue - vuejs2

Comin from this question custom marker for vue2-google-maps
I have markers coming from an endpoint and I am adding markers on created() of a Vue component
<gmap-marker :key="i" v-for="(m,i) in markers" :position="m.position" :clickable="true" #click="toggleInfoWindow(m,i)" :icon="{ url: require('./online.png') }"></gmap-marker>
m has such value
{
infoText: "synno-hlcna",
position: {
lat: 53.3600171,
lng: -6.2630125
},
status: "online"
}
How I can use m.status value in require().
I have tried to add full { url: require('./online.png') } through m.url as well as just require(m.url) and Url was './online.png', It gave me an error as
module not found ./online.png
I want to change the peg colour on the base of status. I have to pngs, online/offline according to m.
How is that possible to bind value in require('./{status}.png') so it may work?
I have tried this way as well
:icon={ url: require('./${m.status}.png') }
UPDATE:
I tried to use v-bind such as
<gmap-marker :key="i" v-for="(m,i) in markers" :position="m.position" :clickable="true" #click="toggleInfoWindow(m,i)" v-bind:icon="{ url: require(m.status) }"></gmap-marker>
its giving error as Cannot find module './online.png' How can we make it work ? it works only if I put ./online.png by myself.

Related

Astro Build Fastify SSR React-Select component not working

I am currently using Astro SSR with Fastify\Node as my server. I created a SSR\Fastify plugin and its working well. I am running into one issue though,and wanted to see if others have faced similar issue. I am not able to use the React-Select component. It works well when running normal Astro-Build without SSR enabled. Once I run the build command I received the following error message when the page tries to load:Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object."
I am leaning towards import issue, but not having any luck narrowing it down.
The type definition is resolving to: react-select/dist/react-selectcjs.d.ts
I get the same error if I use the node ssr plugin as well. I'm not doing anything fancy with the JSX component, this is usage of the react-select:
import Select from "react-select"s
<Select
className="react-select info mx-5 w-100"
classNamePrefix="react-select"
name="singleSelect"
value={pageSelect}
onChange={(value) => {
gotoPage(value.value);
handlePageSelect(value);
}}
options={pageSelectData.map((prop, key) => {
return {
value: key,
label: "Page " + (key + 1),
};
})}
placeholder="Select page"
/>
<Select
className="react-select info mx-5 w-100"
classNamePrefix="react-select"
name="singleSelect"
value={numberOfRows}
onChange={(value) => {
console.log(value);
setPageSize(value.value);
setNumberOfRows(value);
}}
options={numberOfRowsData.map((prop) => {
return {
value: prop,
label: prop + " rows",
};
})}
placeholder="Select #rows"
/>
I found the issue:
I have astro layouts for the following:
SideBarLayout
NavBarLayout
BaseLayout
PageLayout
ContainerLayout
BlocksLayout
BlockLayout
FormLayout
Each of these also leverage a Jsx component. My ContainerLayout and SideBar was missing the client:load value. After correcting that, my forms load properly with event logic and everything and runs withing fastify sever.

Using <object> to embed svg but doesn't show anything

I was trying to use to embed the svg picture but it does not show anything. I looked at some other threads and it was suggested to add type="image/svg+xml", however, it did not solve the issue. When I am trying to look at the DOM for some reason it seems to create an endless loop. I attached the picture
This is the compononent
<template>
<div class="logo">
<object type="image/svg+xml" data="logo.svg">
</object>
</div>
</template>
This is the app.vue
template>
<div id="app">
<Demo></Demo>
</div>
</template>
<script>
import Demo from './components/Demo.vue'
export default {
name: 'app',
components: {
Demo
}
}
</script>
```[![Snapshot][1]][1]
[1]: https://i.stack.imgur.com/Q6ipO.png
This happen because vue-loader doesn’t recognize paths in just any attribute. By default just recognize these ones: https://vue-loader.vuejs.org/options.html#transformasseturls
So, there are 3 possible solutions
Note: If you are not using eslint as linter you could remove eslint comments
1: Bind the route to your image
First add the next variable to your data in the component
data() {
return {
// eslint-disable-next-line global-require
mySvg: require('../assets/logo.svg'),
};
},
Next modify your template
<object type="image/svg+xml" :data="mySvg">
2: Add vue-loader rule
If you don't want to have to bind every svg image, you could add a rule to vue-loader in order to say how to handle data attribute in a object
Go to your webpack config file, if you created the project using vue-cli 3.x you have to create a vue.config.js file in the root (same level that package.json)
// vue.config.js
module.exports = {
chainWebpack: (config) => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap((options) => {
// eslint-disable-next-line no-param-reassign
options.transformAssetUrls = {
object: 'data',
};
return options;
});
},
};
if you want to check that the config was added, execute vue inspect > webpack.config and expect see something like this (inside webpack.config):
{
loader: 'vue-loader',
options: {
...
transformAssetUrls: {
object: 'data'
}
}
}
More info: https://cli.vuejs.org/guide/webpack.html#working-with-webpack
3: Replace default loader and use svg as vue components
Other option is use vue-svg-loader. This loader inlines the SVGs which enables you to modify them using css. Also optimize your files with SVGO
See more: https://vue-svg-loader.js.org/#vue-cli
It is worth checking that you don't have a CSS rule hiding object tags. Otherwise it seems correct. You probably need to check the path and make sure you can reach your image. I assume your filename is a dummy, but try to use an absolute path. And make sure you can hit the path and see the image in your browser.

vuetify doesnt load image in <v-img> although prop shows it has the url

<v-img :src="getPhoto()" height="200px" width="200px"></v-img>
this is for photo to load from getphot function. the src has the url for facebook but vuetify doesnt load anything
computed: {
user () {
return this.$store.getters.user
}
},
methods: {
getPhoto () {
return this.$store.getters.user.photoUrl
}
}
i do not get any error. and when i use the link i can access the image. because i have logged in from my device.
note: i am using firebase for all of these
Try
<v-img :src="require('getPhoto()')" height="200px" width="200px"></v-img>
instead of
<v-img :src="getPhoto()" height="200px" width="200px"></v-img>
Vue loader converts relative paths into require functions automatically for you. Unfortunately, this is not the case when it comes to custom components. You can circumvent this issue by using require. If you're using Vuetify as a Vue-CLI 3 plugin, you can edit your project's vue.config.js file by modifying the options for vue-loader.
// Incorrect
<v-img src="../path/to/img" />
// Correct
<v-img :src="require('../path/to/img')" />
Source: Vuetify
Update: When not using a relative path, I tried creating an example when using a function to get the URL for the image source. I think there are two problems with your code:
Remove the () from getPhoto() in <v-img>
Add the getPhoto() to the computed property.
Here is a Codepen
I hope it helps.

vue: Uncaught TypeError: Cannot read property ... of undefined

I'm using vue#2.1.3 and the vue official webpack template to build an app.
When developing locally, I often see the warning Uncaught TypeError: Cannot read property ... of undefined, but the HTML can be rendered successfully. However, the HTML can't be rendered when it's deployed to Netlify with npm run build command. So I have to treat this warning seriously.
I learned from here that it's because "the data is not complete when the component is rendered, but e.g. loaded from an API." and the solution is to "use v-if to render that part of the template only once the data has been loaded."
There are two questions:
I tried wrap v-if around multiple statements that's generating the warning but personal I think this solution is verbose. Is there a neat approach?
"warnings" in local development turn into "fatal errors"(HTML can't be rendered) in production. How to make them the same? e.g. both of them issue warnings or errors?
Just use v-if on a common parent to all the elements in your template relying on that AJAX call, not around each one.
So instead of something like:
<div>
<h1 v-if="foo.title">{{ foo.title }}</h1>
<p v-if="foo.description">{{ foo.description }}</p>
</div>
Do
<div>
<template v-if="foo">
<h1>{{ foo.title }}</h1>
<p>{{ foo.description }}</p>
</template>
</div>
have you tried to initialize all the data you need? e.g. if you need a b c, you can do:
new Vue({
data: {
a: 1,
b: '',
c: {}
},
created(){
// send a request to get result, and assign the value to a, b, c here
}
})
In this way you wont get any xx is undefined error
Guys are right but I can add something.
If there is possibility that your root element in the condition can be undefined for some reason, it is good practice to use something like that: v-if='rootElement && rootElement.prop'. It will secure you from getting cannot get property prop of undefined as when rootelement is undefined, it will not go further in checking.
2021 vue3
we can use like this
props: {
form: {
type: String,
required: true,
},
setup(props, context) {
console.log(props.form)

DRY for displaying meteor templates for different urls

I am having trouble setting up a simple website with different webpages and staying DRY.
I have everything set up so I the last fragment of the url is the name of the template that needs to be loaded in the content part of the webpage. All I want to do now is load that template in a specific location based on the url.
In any examples, they do this:
{{#if showCreateDialog}}
{{> createDialog}}
{{/if}}
{{#if showInviteDialog}}
{{> inviteDialog}}
{{/if}}
I'd like to do something along the lines of
{{> {{template_name}} }}
Sadly, that doesnt work. I tried this as well:
{{{content}}}
Template.content.content = function () {
var url_frag = Session.get("url_frag");
return Template[url_frag]();
}
This didnt work either. Please help!
Edit:
hmm. perhaps, my error is not in loading the template but in capturing the url:
var TodosRouter = Backbone.Router.extend({
routes: {
"*url": "main"
},
main: function (url) {
Session.set("url", url.split('/'))
}
});
The error I am getting arises when url_frag is undefined...
var url_frag = Session.get("url_frag");
initially, this works, but upon changing webpages, it fails...
Solved. I just left backbone out of it
Template.content.content = function () {
var url = window.location.pathname.split('/');
var url_frag = url.pop()
return Template[url_frag]();
Then in the html:
<template name="content">
{{{content}}}
</template>
You could also try the router smart package at atmosphere, which also supports complex routes and filters.
https://atmosphere.meteor.com/package/router
Install meteorite using npm install -g meteorite
Install router using mrt add router
Add {{renderPage}} to body
Tada! /login now renders {{> login}}
Read the document here: https://github.com/tmeasday/meteor-router