link2055 link2056 link2057 link2058 link2059 link2060 link2061 link2062 link2063 link2064 link2065 link2066 link2067 link2068 link2069 link2070 link2071 link2072 link2073 link2074 link2075 link2076 link2077 link2078 link2079 link2080 link2081 link2082 link2083 link2084 link2085 link2086 link2087 link2088 link2089 link2090 link2091 link2092 link2093 link2094 link2095 link2096 link2097 link2098 link2099 link2100 link2101 link2102 link2103 link2104 link2105 link2106 link2107 link2108 link2109 link2110 link2111 link2112 link2113 link2114 link2115 link2116 link2117 link2118 link2119 link2120 link2121 link2122 link2123 link2124 link2125 link2126 link2127 link2128 link2129 link2130 link2131 link2132 link2133 link2134 link2135 link2136 link2137 link2138 link2139 link2140 link2141 link2142 link2143 link2144 link2145 link2146 link2147 link2148 link2149 link2150 link2151 link2152 link2153 link2154 link2155 link2156 link2157 link2158 link2159 link2160 link2161 link2162 link2163 link2164 link2165 link2166 link2167 link2168 link2169 link2170 link2171 link2172 link2173 link2174 link2175 link2176 link2177 link2178 link2179 link2180 link2181 link2182 link2183 link2184 link2185 link2186 link2187 link2188 link2189 link2190 link2191

[Vue.js] Select2 in Vue.js is not defined

to use Select2 with Vue.js to display some selectable options, but however I implement it, there is always the error:

Uncaught ReferenceError: select2 is not defined

at Object.select2 (external “select2”:1)
at __webpack_require__ (bootstrap:766)
at fn (bootstrap:129)
at Module../src/jquery.js (jquery.js:3)
at __webpack_require__ (bootstrap:766)
at fn (bootstrap:129)
at Module../src/main.js (main.js:1)
at __webpack_require__ (bootstrap:766)
at fn (bootstrap:129)
at Object.0 (Home.vue?1405:1)

I installed the npm package with this command: npm install –save select2. I dont know if this is the official package. I included the cdn link in the index.html and I added a require in a special file (jquery.js) which is directly included in main.js

jquery.js:

import jQuery from ‘jquery’
window.jQuery = window.$ = jQuery
require(‘select2’)

Select2.vue:

<script>
import jQuery from ‘jquery’;
let $ = jQuery;

export default {
name: ‘select2’,
props: [‘options’, ‘value’],

mounted: function () {

var vm = this

$(this.$el).select2({
data: this.options,
tags: true
}).on(‘change’, function () {
vm.$emit(‘input’, this.value)
});
},
watch: {
value: function (value) {
// update value
$(this.$el)
.val(value)
.trigger(‘change’)
},
options: function (options) {
// update options
$(this.$el).empty().select2({data: options,tags: true})
}
},
destroyed: function () {
$(this.$el).off().select2(‘destroy’)
}
}
</script>

Solution :

I also recommend other amazing vue.js component Select2.

But if you cannot convince the boss that you will get the model updated in the vue.js system easy and you hace to spend a lot of time to develop, here are some ideas to try:

Delete jquery.js, and change Select2.vue.js to add require(‘select2’) to select2.vue:

<script>
import jQuery from ‘jquery’;
window.jQuery = window.$ = jQuery;
require(‘select2’);

then, in the parent component use import with relative paths:

import Select2 from “../stangeComponents/Select2.vue”;

I suppose you copy all from the Wrapper Component Example from vue.js docs and everything should work…

Hope it helps :)

[Vue.js] Using google map in Vue / Laravel

Trying to implement google map into vue.js component. But having a hard time. when facing with very awkward situation.

Update 4

How to use forEach or filter to iterate this.estates datas inside the insertMarker function?

data() {
return {
estates:[],
mapName: “map”,
//some other codes
}
},

mounted() {
this.fetchEstates();
this.initMap();
},
methods: {
fetchEstates(page = 1) {
axios.get(‘/ajax’, {
params: {
page
}).then((response) => {
// console.log(response);
this.estates = response.data.data;
this.insertMarkers();
this.meta_data.last_page = response.data.last_page;
this.meta_data.current_page = response.data.current_page;
this.meta_data.prev_page_url = response.data.prev_page_url;
});
},
initMap: function(){

var mapOptions =
{
zoom : 6,
center : {
lat:34.652500,
lng:135.506302
}
};

var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
},

insertMarkers: function() {
console.log(this.estates) // no problem. datas are here.
console.log(this.estates.lat); //undefined returns

var marker = new google.maps.Marker({
map: map,
icon: ‘imgs/marker.png’,
url: “/pages/“ + estates.id,
label: {
text: this.estates.price,
color: “#fff”,
},
position: {
lat: this.estates.lat,
lng: this.estates.lng
}
});

google.maps.event.addListener(marker, ‘click’, function () {
window.location.href = this.url;
});
}
},

Any idea what is going on here???

Solution :

From our discussion in the comments, I realise that the issue is because this.estates is still not defined when initMap() is executed. Remember that you are using an asynchronous operation (via axios) to populate this.estates, so it is undefined at runtime. What you can do is:

Keep the map initialisation logic in initMap()
Move all the Google Map marker creation until after the axios promise has been resolved. You can abstract all that into another method, e.g. insertMarkers()

Also, remember that you need to define estates in the app/component data, otherwise it will not be reactive.

Here is an example:

data() {
return {
mapName: “map”,

// Create the estate object first, otherwise it will not be reactive
estates: {}
}
},

mounted() {
this.fetchEstates();
this.initMap();
},
methods: {
fetchEstates: function(page = 1) {
axios.get(‘/ajax’, {
params: {
page
}).then((response) => {
this.estates = response.data.data;

// Once estates have been populated, we can insert markers
this.insertMarkers();

//pagination and stuff…
});
},

// Iniitialize map without creating markers
initMap: function(){
var mapOptions =
{
zoom : 6,
center : {
lat:34.652500,
lng:135.506302
}
};

var map = new google.maps.Map(document.getElementById(this.mapName), mapOptions);
},

// Helper method to insert markers
insertMarkers: function() {
var marker = new google.maps.Marker({
map: map,
icon: ‘imgs/marker.png’,
url: “/pages/estates.id”,
label: {
text: this.estates.price,
color: “#fff”,
},
position: {
lat: this.estates.lat,
lng: this.estates.lng
}
});

google.maps.event.addListener(marker, ‘click’, function () {
window.location.href = this.url;
});
}
},

[Vue.js] Sorting indexes of an array in javascript

I’m trying to build a small application on Vuejs where I’m having a set of array which comes up through an api response which gives following output:

{
“data”:
{
“Real Estate Regulatory Act”:[
{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}
],
“Environmental Clearance”:[
{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}
],
“Document”:[
{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}
],
“Miscellaneous Approvals”:[
{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}
]
}
}

to sort this javascript as per the indexes with respect to following array:

[‘Document’, ‘Environmental Clearance’, ‘Real Estate Regulatory Act’, ‘Miscellaneous Approvals’]

So my final result will be:

{
“data”:
{
“Document”:[
{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}
],
“Environmental Clearance”:[
{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}
],
“Real Estate Regulatory Act”:[
{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}
],
“Miscellaneous Approvals”:[
{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}
]
}
}

My code currently look like:

if(response.status === 200)
{
let docs = response.data.data;
let sortDocs = [‘Document’, ‘Environmental Clearance’, ‘Real Estate Regulatory Act’, ‘Miscellaneous Approvals’];
let result = []

sortDocs.forEach(function(key) {
this.subscProDocument[key] = result.push(docs[key])
})

}

I get error of something like this:

Uncaught (in promise) TypeError: Cannot read property ‘subscProDocument’ of undefined

I already defined this subscProDocument in data() and initialized as an empty array. Help me out with this. Thanks

Solution :

let data = {
“data”:
{
“Real Estate Regulatory Act”:[
{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}
],
“Environmental Clearance”:[
{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}
],
“Document”:[
{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}
],
“Miscellaneous Approvals”:[
{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}
]
}
};

Get Data from Object and assign to unordered variable

const unordered = data.data;

Declare new Variable ordered

const ordered = {};

Object.keys will get the array of keys from unordered object then will apply sort function on keys for ascending sort.

Then we’ll execute forEach loop on array of keys and will assign value with key to ordered object;

Object.keys(unordered).sort().forEach(function(key) {
ordered[key] = unordered[key];
});

console.log(ordered);

Solution 2:

let obj = {
“data”:
{
“Real Estate Regulatory Act”:[
{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}
],
“Environmental Clearance”:[
{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}
],
“Document”:[
{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}
],
“Miscellaneous Approvals”:[
{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}
]
}
};

const orderedObj = { data: {} };
Object.keys(obj.data).sort().forEach(function(key) {
orderedObj.data[key] = obj.data[key];
});

Solution 3:

You need to take a reference to this as thisArg of Array#forEach

sortDocs.forEach(function(key) {
this.subscProDocument[key] = result.push(docs[key]);
}, this);

or take an arrow function, which takes this of the outer scope.

sortDocs.forEach(key => this.subscProDocument[key] = result.push(docs[key]));

Solution 4:

the data.data object should be an array if you want to order its items, as you can’t rely on the ordering of keys in an Object since it is not guaranteed.
Here is a post about key ordering in JS objects

You can do this ordering and conversion to an array with a single line:

data.data = orderedKeys.map(key => ({ [key]: data.data[key] }));

This will give you:

{
“data”: [
{
“Document”: [{
“id”: 601,
“project_id”: 2392,

}]
},
{
“Environmental Clearance”: [{
“id”: 602,
“project_id”: 2392,

}]
},
{
“Real Estate Regulatory Act”: [{
“id”: 603,
“project_id”: 2392,

}]
},
{
“Miscellaneous Approvals”: [{
“id”: 604,
“project_id”: 2392,

}]
}
]
}

Here is a working example:

const data = {
“data”: {
“Real Estate Regulatory Act”: [{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}],
“Environmental Clearance”: [{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}],
“Document”: [{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}],
“Miscellaneous Approvals”: [{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}]
}
};

const orderedKeys = [‘Document’, ‘Environmental Clearance’, ‘Real Estate Regulatory Act’, ‘Miscellaneous Approvals’];

data.data = orderedKeys.map(key => ({ [key]: data.data[key] }));

console.log(data)

Solution 5:

This is the solution:

var obj={
“data”:
{
“Real Estate Regulatory Act”:[
{
“id”:603,
“project_id”:2392,
“parent_type”:”Real Estate Regulatory Act”,
“type”:”Building Plan Approval”,
“name”:”FORMS.pdf”,
“link”:”https://…..DyumatHotelsFORMS.pdf”
}
],
“Environmental Clearance”:[
{
“id”:602,
“project_id”:2392,
“parent_type”:”Environmental Clearance”,
“type”:”Form 1”,
“name”:”HotelsCPEMP.pdf”,
“link”:”https://…..MarineandDyumatHotelsCPEMP.pdf”
}
],
“Document”:[
{
“id”:601,
“project_id”:2392,
“parent_type”:”Document”,
“type”:”Land Details”,
“name”:”FORMS.pdf”,
“link”:”https://….HotelsFORMS.pdf”
}
],
“Miscellaneous Approvals”:[
{
“id”:604,
“project_id”:2392,
“parent_type”:
“Miscellaneous Approvals”,
“type”:”Not Reported”,
“name”:”Report Part 1.pdf”,
“link”:”https://…Report Part 1.pdf”
}
]
}
};

function map(it){
var item={};
item[it]=obj.data[it];
return item;
}

console.log(Object.keys(obj.data).sort().map(map));

[Vue.js] How to ignore 'firebase-admin appears to have been installed in an unsupported environment.'?

I’m using firebase and I’m building an admin dashboard for my team. The dashboard is used to add content to our platform that all users will be able to see.

At first I implemented it using the Firebase JS SDK with the security rules disabled to test it. So far everything ok. Then I tried to move the dashboard to another vue.js project with the Firebase Admin SDK for node.js that will be used on secure machines with ServiceAccount.json credentials.

Although, running a node.js project without vue.js works just fine, the vue.js project display the following warning that does not apply to my use case. No operations are then permitted and I receive a bunch of different errors.

Is there a way to ignore this warning and make Firebase Admin SDK respond? I can implement a Node.js / Express server locally to make redirect the request but if I don’t miss anything this sounds like a waste of time?

\======== WARNING! ========

firebase-admin appears to have been installed in an unsupported environment.
This package should only be used in server-side or backend Node.js environments, and should not be used in web browsers or other client-side environments.

Use the Firebase JS SDK for client-side Firebase integrations:

https://firebase.google.com/docs/web/setup

Solution :

Using the Firebase Admin SDK for Node.js is only supported on server-side Node.js environments. It is not supported in client-side Node.js or other JavaScript environments.

If you want to expose functionality from the Admin SDK into the client, you will have to wrap that functionality in an API endpoint, either on a server you control, or through Cloud Functions.

[Vue.js] How vue.js reactivity works under the hood?

when really desperate and looking forward to the help guys. Thanks in advance so much.

Basically, When there is a component, lets call it TransportComponenet.vue, and in that component, there is a data() and My properties are carId, transportId. What vue.js does is makes getters and setters for these properties. Lets say in this componenets view, I type {carId + transportId} and also {carId * transportId}.

As far As I know, vue.js comes to my views, looks at them, and wherever there is getters ( {carId+ transportId} or {carId * transportId} ) are getters. So vue.js comes and registers them in components watcher. When I somewhere use setters such as this.carId = 5. vue.js does the setter function for this property and reevalutes the functions (getters) that were saved before in the watcher. Is this the correct assumption?

What I dont get it, is what relationship does exist between Dep class and Watcher class ? I know they both play the big role. Id really honor the whole explanation which thing goes where and when and why. I really do hope that I can find the big help here.

I tried a lot by myself , but I need the help still. Looking forward to the help.

Solution :

Reactivity is automatic synchronization between the state and the DOM. That’s what the view libraries like vue.js and React try to do in their core. They do that in their own ways.

I see Vue’s reactivity system as being two fold. One side of the coin is the DOM update mechanism. Let’s look into that first.

Let’s say you have a component with a template like:

<template>
<div>{ foo }</div>
</template>

<script>
export default {
data() {
return {foo: ‘bar’};
}
}
</script>

This template gets converted into render function. This happens during build time using vue-loader. The render function for the template above looks something like:

function anonymous(
) {
with(this){return _c(‘div’,[_v(_s(foo))])}
}

Render function runs on the browser and when executed returns a Vnode (virtual node). A virtual node is just a simple JavaScript object that represents the actual DOM node, a blueprint for the DOM node. The above render function when executed would return something like:

{
tag: ‘div’,
children: [‘bar’]
}

vue.js then creates actual DOM node from this Vnode blueprint and places it into the DOM.

Later, let’s say the foo’s value changes and somehow the render function runs again. It will give a different Vnode. vue.js then diffs the new Vnode with the old one and patches only the necessary changes required into the DOM.

This gives us a mechanism to update the DOM efficiently taking the latest state of things for a component. If every time the render function of a component gets called when any of its state (data, props etc) changes, we have the full reactivity system.

That’s where the other side of Vue’s reactivity coin comes in. And that is the reactive getters and setters.

This will be a good time to understand Object.defineProperty API if you are not already aware of that. Because Vue’s reactivity system relies on this API.

TLDR; it allows us to override an object’s property access and assignment with our own getter and setter functions.

When vue.js instantiates the component, it walks through all the properties of the data and props and redefines them using Object.defineProperty.

What it actually does is, it defines getters and setters for each of the data and props properties. By doing so, it overrides the dot access (this.data.foo) and the assignment (this.data.foo = someNewValue) of that property. So whenever these two actions occur on that property, our overrides get invoked. So we have a hook to do something about them. We will get back to this in a bit.

Also, for each property a new Dep() class instance is created. It’s called Dep because each data or props property can be a dependency to the component’s render function.

But first, it’s important to know that each component’s render function gets invoked within a watcher. So a watcher has an associated component’s render function with it. Watcher is used for other purposes as well, but when it is watching a component’s render function, it is a render watcher. The watcher assigns itself as the current running watcher, somewhere accessible globally (in Dep.target static property), and then runs the component’s render function.

Now we get back to the reactive getters and setters. When you run the render function, the state properties are accessed. E.g. this.data.foo. This invokes our getter override. When the getter is invoked, dep.depend() is called. This checks if there is a current running watcher assigned in Dep.target, and if so, it assigns that watcher as the subscriber of this dep object. It’s called dep.depend() because we are making the watcher depend on the dep.

_______________ _______________
| | | |
| | subscribes to | |
| Watcher | ————–> | Dep |
| | | |
|_____________| |_____________|

Which is the same as

_______________ _______________
| | | |
| Component | subscribes to | it’s |
| render | ————–> | state |
| function | | property |
|_____________| |_____________|

Later, when the state property gets updated, the setter is invoked and the associated dep object notifies its subscribers about the new value. The subscribers are the watchers which are render function aware and that’s how the components render function gets invoked automatically when its state changes.

This makes the reactivity system complete. We have a way to call a component’s render function whenever its state changes. And we have a way to efficiently update the DOM once that happens.

This way vue.js has created a relationship between a state property and a render function. vue.js knows exactly which render function to execute when a state property changes. This scales up really well and basically removes a category of performance optimization responsibility from the hands of developer. Devs don’t need to worry about over rendering of components no matter how big the component tree. To prevent this, React e.g. provides PureComponent or shouldComponentUpdate. In Vue, this is just not necessary since vue.js knows exactly which component to re-render when any state changes.

But now that we know how vue.js makes things reactive, we can think of a way to optimize things a bit. Imagine you have a blog post component. You get some data from the backend and show them on the browser using vue.js component. But there is no need for the blog data to be reactive because it most likely won’t change. In such situation, we can tell vue.js to skip making such data reactive by freezing the objects.

export default {
data: () => ({
list: {}
}),
async created() {
const list = await this.someHttpClient.get(‘/some-list’);

this.list = Object.freeze(list);
}
};

Oject.freeze among other things disables the configurability of an object. You cannot redefine the properties of that object again using Object.defineProperty. So vue.js skips the whole reactivity setup work for such objects.

Besides, going through the vue.js source code yourself, there are two extremely good resources available on this topic:

vue.js Mastery’s Advanced component course
FrontendMaster’s Advanced Vue.js Features from the Ground Up by Evan You

If you are curious about the internals of a simple virtual DOM implementation, check out the blog post by Jason Yu.

Building a Simple Virtual DOM from Scratch

[Vue.js] Using v-else-if and events VueJS

i’m new at VueJS, and i getting a litle trouble to understand how to use Events with v-else-if. What i’m trying to do is when the user input a number, a text will be show to him! This is what i got so far:

HTML:

<script src=”https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>

<div id=”app”>
<p v-if=”number === ‘1’”>You can see me!</p>
<p v-else-if=”number === ‘2’”>Do you also see me?</p>
<p v-else>Hello</p>
<input v-on:input=”changeText”>
</div>
<script src=”app.js”></script>

VueJS:

new Vue({
el: ‘#app’,
data: {
number: ‘1’,
},
methods: {
changeText = function(event){
this.number = event.target.value;
}
}
})

Can somebody help? Thanks so much you all!

Solution :

the syntax of defining the methods is off; You either do:

changeText (event){

}

Or:

changeText: function(event){

}

Solution 2:

I’m leaving this comment for perpetuity, as Psidom’s comment perfectly fixes the problem. The original issue is due to incorrect syntax, using changeText: function(event){ … } will fix the problem. If you open the browser’s devtool console, you will immediately see a syntax error being logged.

However, this issue can be completely avoided if the method is not declared at the first place. Since you are actually simply trying to use an <input> element to directly modify the component’s data, you can do it via using v-model. This can dramatically reduce redundancy in the code, especially when you have multiple input elements.

In the case, using <input v-model=”number”> will work perfectly fine:

new Vue({
el: ‘#app’,
data: {
number: ‘1’
}
})
<script src=”https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>

<div id=”app”>
<p v-if=”number === ‘1’”>You can see me!</p>
<p v-else-if=”number === ‘2’”>Do you also see me?</p>
<p v-else>Hello</p>
<input v-model=”number”>
</div>

[Vue.js] Property or method contact is not defined on the instance but referenced during render Vuejs Laravel

I’m developing chat app on laravel using vue.js and i’m new to vue.js.

but i’m getting below mentioned error, please help me solve this

Error1 :
[vue.js warn]: Property or method “contact” is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property

Error2 :
[vue.js warn]: Error in render: “TypeError: Cannot read property ‘avatar’ of undefined”

/ ChatApp.vue.js file/

<template>
<div class=”chat-app”>
<Conversation :contact=”selectedContact” :messages=”messages”/>
<ContactsList :contacts=”contacts”/>
</div>
</template>

<script>
import Conversation from ‘./Conversation.vue’;
import ContactsList from ‘./ContactsList.vue’;

export default {
props: {
user: {
type: Object,
required: true
}
},
data(){
return {
selectedContact: null,
messages: [],
contacts: []
};
},
mounted(){
axios.get(‘/contacts’)
.then((response) => {
this.contacts = response.data;
});
},
methods: {
startConversationWith(contact) {
axios.get(`/conversation/$(contact.id)`)
.then((response) => {
this.messages = response.data;
this.selectedContact = contact;
})
}
},
components: { ContactsList, Conversation }
};
</script>

/ ContactsList.vue.js file/

<template>
<div class=”contacts-list”>
<ul v-if=”contacts.length > 0”>
<li v-for:”(contact, index) In contacts” :key=”contact.id”
@click=”selectContact(index, contact)” :class=”{ ‘selected’ : index ==
selected}”>
<div class=”avatar”>
<img :src=”contact.avatar” :alt=”contact.name”>
</div>
<div class=”contact”>
<p class=”name”>{ contact.name }</p>
<p class=”email”>{ contact.email }</p>
</div>
</li>
</ul>
</div>
</template>

<script>
export default {
props: {
contacts: {
type: Array,
default: []
}
},
data() {
return {
selected: 0
};
},
methods: {
selectContact(index, contact) {
this.selected = index;
this.$emit(‘selected’, contact);
}
}
};
</script>

/ conversation.vue.js /

<template>
<div class=”conversation”>
<h1>{ contact ? contact.name : ‘Select a contact’ }</h1>
<MessagesFeed :contact=”contact” :messages=”messages” />
<MessageComposer @send=”sendMessage” />
</div>
</template>

<script>
import MessagesFeed from ‘./MessagesFeed.vue’;
import MessageComposer from ‘./MessageComposer.vue’;

export default {
props: {
contact: {
type: Object,
default: null
},
messages: {
type: Array,
default: []
}
},
methods:{
sendMessage(text) {
console.log(text);
}
},
components: {MessagesFeed, MessageComposer}
};
</script>

Solution :

I guess you can do it like that:

<ul v-if=”contacts.length > 0”>
<li v-for=”contact in contacts” :key=”contact.id”>
<div class=”avatar”>
<img :src=”contact.avatar” :alt=”contact.name”>
</div>
<div class=”contact”>
<p class=”name”>{ contact.name }</p>
<p class=”email”>{ contact.email }</p>
</div>
</li>
</ul>

Solution 2:

@Akash you can use it this way :

data() {
return {
contactsNotEmpty:false
}
},
// …
mounted() {
axios.get(‘/contacts’)
.then((response) => {
this.contacts = response.data;
this.contactsNotEmpty = true;
});
}

<ul v-if=”contactsNotEmpty”>

</ul>

also you may check this vuejs article about what is happening : https://vuejs.org/2016/02/06/common-gotchas/#Why-isn%E2%80%99t-the-DOM-updating

Solution 3:

The first error is throwing in the Conversation.vue, you were passing data to a child component, you have to make sure it is defined as a prop in that component

export default{
props: [‘contact’]
};

and if it is defined, the prop type is not expecting a null value. I would change it to string and on rendering in my ChatApp.vue, I would set selectedContact to string.Empty||’’

For the second error, the avatar key is missing from the response object. You have to check if it is present first before accessing it. Kindly refer to El Alami Anas’s answer above.

[Vue.js] Ways to import a JSON file in public folder in Vue-CLI

to import a JSON file to use it, I need it to modify it in the future so I put it in public folder not assets, When I refer to it like this import JSON from ../../public/Data.json it works but I don’t think so after building project can be resolved because after building there is no public folder. So I tried this :

let addr = process.env.BASE_URL;
import JSON from `${addr}Data.json`;

But It throws an error : SyntaxError
I’m confused now which way is the best and is there another way ?

Solution :

The assets in the public folder are copied as is to the root of the dist folder. In the code, you can reference it just as /Data.json (if the app is deployed at the root of the domain).

E.g

async someMethod() {
const baseUrl = process.env.BASE_URL;
const data = await this.someHttpClient.get(`${ baseUrl }/Data.json`);
}

If you want to import the JSON as you have tried, I suggest to put it somewhere in the src folder and import from there

E.g.

import data from ‘@/data/someData.json’

console.log(data);

[Vue.js] Format table to show data in correct columns and rows

when trying to create a table that places all the answers that the user has answered by buying a ticket under the correct questions, and if they haven’t answered then show the dash symbol.

The problem is that if there are more than on tickets that the user has purchased then the answers get all messed up.

Example:

So, for this the number should go under ‘Mobile Num?’ in the same row as ‘Free 2’ and ‘Male’, ‘Aadil’ and ‘20’ should go under ‘Gender?’, ‘Name?’ and ‘Age?’ in the same row as Free.

This is my HTML:

<template>
<fragment>
<tr>
<td :rowspan=”countArray + 1”>
<img :src=”user.profile_image”>
</td>

<td :rowspan=”countArray + 1”>
{user.first_name + “ “ + user.last_name}
</td>

<td :rowspan=”countArray + 1”>
<div v-for=”(nameTick, nameKey) in name” :key=”nameKey” class=”tdStyle”>
<td>
{nameTick}
</td>
</div>
</td>
</tr>

<tr v-for=”(ticketQues, quesKey) in ticketAns” :key=”quesKey”>
<td v-for=”(ans, ansKey) in ticketQues.questions” :key=”ansKey”>
{ans.answer}
</td>
</tr>
</fragment>
</template>

This is my JS:

beforeMount: function() {
this.$axios.$get(`/user/${this.userId}`).then(response => {
this.user = response
});

for (let i = 0; i < this.ticketName.tickets.length; i++) {
this.tickets_name = this.ticketName.tickets[i].ticket_name;
this.countArray = this.ticketName.tickets[i].count;
this.name.push(this.tickets_name);
};
},

watch: {
tickets: {
handler: function(val) {
for (let x = 0; x < val.length; x++) {
this.$axios.$get(`/ticket/${val[x].id}/answer`).then(response => {

for (let i = 0; i < response.questions.length; i++) {
this.userAnswered = response.questions[i];

this.answered.push(this.userAnswered.answer);
}
console.log(response)
this.allQuestions = this.ticketAns.push(response);
})
}
// this.userAnswers.push(this.ticketAns);
this.userAnswers.push(this.answered);
}
}
}

If someone can help it would be much appreciated.

Solution :

Remove the <td> inside <td>, after that use a <div> with grids and css to organize inside the <div>.

<template>
<fragment>
<tr>
<td :rowspan=”countArray + 1”>
<img :src=”user.profile_image”>
</td>

<td :rowspan=”countArray + 1”>
{user.first_name + “ “ + user.last_name}
</td>

<td :rowspan=”countArray + 1”>
<div v-for=”(nameTick, nameKey) in name” :key=”nameKey” class=”tdStyle”>
<div class=”ui grid”>
{nameTick}
</div>
</div>
</td>
</tr>

<tr v-for=”(ticketQues, quesKey) in ticketAns” :key=”quesKey”>
<td v-for=”(ans, ansKey) in ticketQues.questions” :key=”ansKey”>
{ans.answer}
</td>
</tr>
</fragment>
</template>

[Vue.js] vue.js element selected by focus is not reactive

there is a listener to check what input was selected at last to add some kind of string/variable later into it.

created: function () {
document.addEventListener(‘focusin’, this.focusChanged);
}

focusChanged(event) {
if (event.target.id !== ‘variable-search’) {
this.lastElement = event.target;
}
}

This seems to work fine, and when I click on an input field this.lastElement gets updated with the focused element. All these inputs have a v-model which can be a string in an object or just a plain string.

Now the thing is when I try to update the value by:

this.lastElement.value += variable;

vue.js won’t detect its changes, also in the vue.js Developer tools the string won’t get updated. But in the input field it does get updated. So this should be a reactivity thing.

When I add a new character into the input field (v-model) it does update again. So it’s just when I update the string by this.lastElement it won’t register its changes.

The thing is that the input fields are dynamic, so I don’t know how many input fields are here and how many lists etc. So I need vue.js to re-render the variable after the value of lastElement is updated.

Edit

I just tried it with an @focus here an example

<input v-model=”testVar” @focus=”lastElement = testVar”>

If I update lastElement later on it doesn’t update it for testVar but just for lastElement.

Solution :

Changing values in DOM elements programmatically does not cause DOM events to fire. v-model relies on input (or change when using .lazy) events to update its bound variable. If you dispatch those events when you update the value in an input, the variable will react.

new Vue({
el: ‘#app’,
data: {
items: [‘one’,’two’,’three’]
},
methods: {
addAddress() {
this.lastElement.value += ‘address’;
this.lastElement.dispatchEvent(new Event(‘input’));
this.lastElement.dispatchEvent(new Event(‘change’));
},
focusChanged(event) {
this.lastElement = event.target;
}
}
})
<script src=”https://unpkg.com/vue@latest/dist/vue.js"></script>
<div id=”app”>
<div v-for=”item, index in items”>
<input v-model=”items[index]“ @focus=”focusChanged”>
{item}
</div>
<button type=”button” @click=”addAddress”>+address</button>
</div>

Solution 2:

You could add a ref attribute to each of the inputs and use the ref to update their values. For example, an input element could be:

<input v-model=”testVar” ref=”input1” id=”input1” @focus=”focusChanged”>

In the methods:

methods: {
focusChanged(event) {
if (event.target.id !== ‘variable-search’) {
this.lastElement = event.target.id;
}
},
}

And where you want to update the value: this.$refs[this.lastElement].value += variable;

Solution 3:

I think you are relying too much on dom functions, etc. (imho). A very practical way is to store the data inside the component and then render the data. Any events (clicks, change or focus) should be handled by the component and modifiy the data inside the component. Any change will then be rendered automatically.

If you have this template:

<div id=”app” class=”container”>
<div v-for=”field in fields”>
<label for=”{field}”>{field}</label>
<input type=”text” id=”{field}” value=”{values[field]}”/>
<button @click=”setValue(field)”>set {field}</button>
</div>
</div>

You can have a component like this:

new Vue({
el: ‘#app’,
data: function () {
return {
values: {‘address’: ‘a’, ‘subject’: ‘b’}
}
},
computed: {
fields: function () {
return Object.keys(this.values)
}
},
methods: {
setValue: function (v) {
this.values[v] = v
}
}
});

Here is a working codepen: https://codepen.io/mbuechmann/pen/XOMObG?editors=1010

when not quite sure, if I understood you question correctly. But in this example you could now e.g. add a “send” button to send the email.

This all works without any DOM functions.