link1370 link1371 link1372 link1373 link1374 link1375 link1376 link1377 link1378 link1379 link1380 link1381 link1382 link1383 link1384 link1385 link1386 link1387 link1388 link1389 link1390 link1391 link1392 link1393 link1394 link1395 link1396 link1397 link1398 link1399 link1400 link1401 link1402 link1403 link1404 link1405 link1406 link1407 link1408 link1409 link1410 link1411 link1412 link1413 link1414 link1415 link1416 link1417 link1418 link1419 link1420 link1421 link1422 link1423 link1424 link1425 link1426 link1427 link1428 link1429 link1430 link1431 link1432 link1433 link1434 link1435 link1436 link1437 link1438 link1439 link1440 link1441 link1442 link1443 link1444 link1445 link1446 link1447 link1448 link1449 link1450 link1451 link1452 link1453 link1454 link1455 link1456 link1457 link1458 link1459 link1460 link1461 link1462 link1463 link1464 link1465 link1466 link1467 link1468 link1469 link1470 link1471 link1472 link1473 link1474 link1475 link1476 link1477 link1478 link1479 link1480 link1481 link1482 link1483 link1484 link1485 link1486 link1487 link1488 link1489 link1490 link1491 link1492 link1493 link1494 link1495 link1496 link1497 link1498 link1499 link1500 link1501 link1502 link1503 link1504 link1505 link1506

[Vue.js] Transform grouped query into Object tree Subscribe to RSS

to transform the result of a query to a tree object in js, each field of the query is beign added in an array like [‘field2’, ‘field3’] in the js file, so the back end create the dynamic query with it, the tree must be created from left to right most external to most internal field (the query is also being grouped by the id of the fields), this is the query (remember, the fields are dynamic so more fields are added), the last branch of the tree should be the quantities (wich are dynamic too)

SELECT
T2.field2 as field2, T3.field3 as field3, SUM(quantity) AS quantity
FROM
table1 T1
INNER JOIN
table2 T2 ON T1.table2_id = T2.id
INNER JOIN
table3 T3 ON T1.table3_id = T3.id
WHERE
AND T1.date = 20190611
GROUP BY T1.table2_id, T1.table3_id

this will give me a set of data like this

‘Group 1’, ‘Data 0’, ‘9172’
‘Group 1’, ‘Data 1’, ‘789’
‘Group 1’, ‘Data 22’, ‘289’
‘Group 1’, ‘Data 3’, ‘254’
‘Group 1’, ‘Data 4’, ‘197’
‘Group 1’, ‘Data 55’, ‘173’
‘Group 2’, ‘Data 0’, ‘38’
‘Group 2’, ‘Data 11’, ‘3’
‘Group 2’, ‘Data 4’, ‘4’
‘Group 3’, ‘Data 0’, ‘807’
‘Group 3’, ‘Data 1’, ‘40’
‘Group 3’, ‘Data 18’, ‘4’
‘Group 3’, ‘Data 2’, ‘35’

What i need to do is to trasform it to somethig like this.

[
{
field2: ‘Group 1’,
data: [
{
field3: ‘Data 0’,
data: [
{ quatity: 9172 },
],
},
{
field3: ‘Data 1’,
data: [
{ quatity: 789 },
],
},
{
field3: ‘Data 3’,
data: [
{ quatity: 289 },
],
},
{
field3: ‘Data 4’,
data: [
{ quatity: 197 },
],
},
{
field3: ‘Data 55’,
data: [
{ quatity: 173 },
],
},
],
},
{
field2: ‘Group 2’,
data: [
{
field3: ‘Data 0’,
data: [
{ quatity: 38 },
],
},
{
field3: ‘Data 11’,
data: [
{ quatity: 3 },
],
},
{
field3: ‘Data 4’,
data: [
{ quatity: 4 },
],
},
],
},
{
field2: ‘Group 3’,
data: [
{
field3: ‘Data 0’,
data: [
{ quatity: 807 },
],
},
{
field3: ‘Data 1’,
data: [
{ quatity: 40 },
],
},
{
field3: ‘Data 18’,
data: [
{ quatity: 4 },
],
},
{
field3: ‘Data 2’,
data: [
{ quatity: 35 },
],
},
],
},
]

The trick here is that the fields in the query are dynamic so i need to keed looking until it reach the last field in the list, so if the field array have a items like [‘field2’, ‘field3’, ‘field4’] and the array of values have an array like [‘quantity’, ‘balance’]
the result should be something like

[
{
field2: ‘Group 1’,
data: [
{
field3: ‘Data 0’,
data: [
{
field4: ‘Last field,
data: [
{ quantity: 3435, balance: 43.53 },
],
},
{
field4: ‘Last field,
data: [
{ quantity: 234, balance: 241.53 },
],
},
],
},
],
},
]

How could achieve this?

Solution :

You could take a combined approach by using the keys and values array and look for same objects.

var data = [[‘Group 1’, ‘Data 0’, ‘9172’], [‘Group 1’, ‘Data 1’, ‘789’], [‘Group 1’, ‘Data 22’, ‘289’], [‘Group 1’, ‘Data 3’, ‘254’], [‘Group 1’, ‘Data 4’, ‘197’], [‘Group 1’, ‘Data 55’, ‘173’], [‘Group 2’, ‘Data 0’, ‘38’], [‘Group 2’, ‘Data 11’, ‘3’], [‘Group 2’, ‘Data 4’, ‘4’], [‘Group 3’, ‘Data 0’, ‘807’], [‘Group 3’, ‘Data 1’, ‘40’], [‘Group 3’, ‘Data 18’, ‘4’], [‘Group 3’, ‘Data 2’, ‘35’]],
keys = [‘field2’, ‘field3’],
values = [‘quantity’],
result = data.reduce((r, a) => {
keys
.reduce((q, k, i) => {
var temp = q.find(o => o[k] === a[i]);
if (!temp) q.push(temp = { [k]: a[i], data: [] });
return temp.data;
}, r)
.push(Object.assign({}, …values.map((k, i) => ({ [k]: a[keys.length + i] }))));
return r;
}, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

[Vue.js] Nuxtjs handler.call is not a function Subscribe to RSS

been banging my head once more.

I’m surprised I haven’t seen a similar question here on SOF, but it’s really weird.
This code WAS working, but I moved into a standalone component to be used on multiple pages.
This is the error I’m getting when I go to the page:

handler.call is not a function

I know for a fact it is this component because if I remove the component from the page, there is no error and runs fine. The component calls no functions and has no functions in the script. there is no idea what is going on.

and in the console log, there isn’t much help either:

TypeError: “handler.call is not a function”
NuxtJS 21

invokeWithErrorHandling

callHook

insert

invokeInsertHook

patch

_update

updateComponent

get

Watcher

mountComponent

$mount

mount

_callee5$

tryCatch

invoke

method

asyncGeneratorStep

_next

run

notify

flush

This is the very simple component source code:

<template>
<div>
<button v-if=”can_edit” class=’btn-blue’> Edit </button>
<div v-for=”card in cards” class=’my-credit-card’ v-bind:key=”card.id”>
<h5>{card.name}</h5>
<h5 class=’mt-0’> {card.last4}</h5>
<p class=’small’>Exp. {card.expiration}</p>
</div>
<div v-if=”cards.length == 0”>
<p class=’subtle’>
the saved payment methods will display here once you send the first card!
</p>
</div>
<a v-if=”(can_add && cards.length > 0)” href=”/add-card” class=’action’> + Add New Card </a>
</div>
</template>
<script>
export default {
data : function(){
return {
cards : [
{
id: 1,
name: “Lisa Smith”,
last4: “4231”,
expiration: “12/2022”
},
{
id: 2,
name: “John Smith”,
last4: “1234”,
expiration: “11/2023”
},
],
};
},
props : {
can_add : {
default : true,
type: Boolean,
},
can_edit : {
default : true,
type: Boolean,
},
},
mounted : {
// fetch cards
},
}
</script>

and this is how I’m importing the component:

<template>
<section class=’container’>
<h1>My Credit Cards</h1>
<mycards :can_add=”true” :can_edit=”true”></mycards>
</section>
</template>
<script>
import mycards from ‘~/components/my_cards.vue’;
export default {
data : function(){
return {
test : 1,
};
},
components : {
mycards,
},
}
</script>

Solution :

This:

mounted : {
// fetch cards
},

Should be:

mounted () {
// fetch cards
},

You’re setting the mounted hook to an object, which won’t have a call method on it.

[Vue.js] How to Prevent downcase or lowercase conversion of attribute names for a Vue component with Jeykll Subscribe to RSS

I’m using a vue.js component, vue-carousel, in a Jekyll project. Everything is working except the control via attributes because the component is expecting camel case but Jekyll converts attributes to lowercase. So my code:

<carousel
:perPage=”1”
:navigationEnabled=”true”
:navigationNextLabel=”‘’”
:navigationPrevLabel=”‘’”
:paginationEnabled=”false”
class=”gr__carousel”>

</carousel>

gets generated with attributes:

<div
class=”VueCarousel gr__carousel”
perpage=”1”
navigationenabled=”true”
navigationnextlabel=””
navigationprevlabel=””>

</div>

one solution from Why Jekyll convert my Capital words into lowercase in Categories

was to edit the Jekyll gem but I would like to avoid this if possible. Is there any other work around for this situation?

Solution :

vue.js allows the attributes used for passing props to use either camelCase or kebab-case. So if Jekyll is causing problems with :perPage you can just use :per-page instead.

https://vuejs.org/v2/guide/components-props.html#Prop-Casing-camelCase-vs-kebab-case

https://vuejs.org/v2/style-guide/#Prop-name-casing-strongly-recommended

vue.js will normalize these prop names when creating the component instances, so they’ll always be accessible using camelCase on the instance. So it’ll be this.perPage no matter how you pass it.

I’m not 100% sure but I think the conversion is done in normalizeProps:

https://github.com/vuejs/vue/blob/3819af5c9dedde4d1ea81f9caa127e611c8752e3/src/core/util/options.js#L294

[Vue.js] Passing axios data to view template Subscribe to RSS

when creating a simple SPA using vue.js and axioz as a scripts (not cli, etc)

So far when able to pull data from a json then render and paginate the list,and when an item is clicked when able to console log the data for the specific entry.

HTML

<!–app–>
<div id=”app”>

<!–articles–>
<div class=”row” style=”background: #111; padding: 8em 0; width: 50%;”>
<div class=”ctr”>
<div class=”row articles page_content” style=”padding: 0;”>
<ul>
<li v-for=”(post) in displayedPosts” @click=”getSingle(post.id)”>
<router-link :to=”{ path: ‘/post/‘+ post.id}” class=”flex” >
<div class=”row article_thumb”>
<img :src=”post.url” :alt=”post.title”/>
</div>
<div class=”row article_excerpt”>
<h3 class=”title”>{post.title }</h3>
</div>
</router-link>
</li>
</ul>
</div>
<div class=”row pagination”>
<button type=”button” v-if=”page != 1” @click=”page–”> << </button>
<button type=”button” v-for=”pageNumber in pages.slice(page-1, page+5)” @click=”page = pageNumber”> {pageNumber} </button>
<button type=”button” @click=”page++” v-if=”page < pages.length”> >> </button>
</div>
</div>
</div>
<!–articles–>

<div class=”row” style=”background: #000; padding: 8em 0; width: 50%;”>
<div class=”flex router”>
<router-view></router-view>
</div>
</div>

</div>
<!–app–>

VUE.JS

const Home = {
template: “<div><h1>Click an article to update this view</h1></div>”
};

//post
var Post = {
template:
‘<div class=”row”><h1>Display data for Post ID # {$route.params.id} here</h1><p style=”color: red;”>This is where when stuck, cant display the post data, see example below.</p><p>{title}</p></div>’,

//post methods
methods: {
//get single post
getSingle: function(id) {
var self = this;
this.id = this.$route.params.id;
this.title = this.title;
axios
.get(this.baseUrl, {
params: {
id: this.id,
}
})
.then(response => {
this.post = response.data;
this.title = response.data.title;
console.log(this.title);
console.log(this.post);
console.log(“You clicked post ID #” + this.id);
})
.catch(response => {
console.log(error);
});
}
},
//post methods

//post data
data() {
return {
baseUrl: “https://jsonplaceholder.typicode.com/photos",
posts: [],
title: this.title
};
},

//post created
created() {
this.getSingle(this.$route.params.id);
},

watch: {
“$route.params”: {
handler(newValue) {
const { id } = newValue;
this.getSingle(id);
},
immediate: true
}
}
};
//post

//router
const router = new VueRouter({
routes: [
{ path: “/“, component: Home },
{ path: “/post/:id”, component: Post }
]
});

//initial state
var paginationApp = new Vue({
el: “#app”,
router: router,
data: {
posts: [],
baseUrl: “https://jsonplaceholder.typicode.com/photos",
page: 1,
perPage: 2,
pages: []
},

//initial state methods
methods: {

//get single
getSingle() {},

//get posts
getPosts() {
axios
.get(this.baseUrl)
.then(response => {
this.posts = response.data;
})
.catch(response => {
console.log(response);
});
},

//set pages
setPages() {
let numberOfPages = Math.ceil(this.posts.length / this.perPage);
for (let index = 1; index <= numberOfPages; index++) {
this.pages.push(index);
}
},

//paginate
paginate(posts) {
let page = this.page;
let perPage = this.perPage;
let from = page * perPage - perPage;
let to = page * perPage;
return posts.slice(from, to);
}
},

//created
created() {
this.getPosts();
},

//watch
watch: {
posts() {
this.setPages();
}
},

//computed
computed: {
displayedPosts() {
return this.paginate(this.posts);
}
}
});
//initial state

Or see this codepen for full example https://codepen.io/flashvenom/pen/YozyMx and be sure to checkout the console log.

My problem is i cannot console log the title or any internal fields of the data object, as to be able to add the title etc into the view area.

Any help or pointers would be much appreciated.

Solution :

The response is in array form and you cannot access array object element without looping array.

If you wish to get title of first post, then you can do as shown below,

this.title = response.data[0].title

To access all posts title, you can use v-for loop in you vue.js template. Here is little example on how you can accomplish that,

<div v-for=”post in posts”>
<span>{ post.title }</span>
</div>

[Vue.js] vue.nextTick false positive Subscribe to RSS

context:

const Constructor = Vue.extend(MyComponent);
function createComponent() {
vm = new Constructor({
props,
}).$mount();

return vm;
}

Question:
While on tests, I find

vm.$nextTick().then(() => {
expect(result).to.equal(expectedResult);
})

and

vm.$nextTick().then(() => {
expect(result).to.not.equal(expectedResult);
})

both passing.
How to get rid of this situation ? Would aync await in someway make sure the truth only passes ?

Solution :

First: Just because you can negate any assertion with .not doesnt mean you should. With great power comes great responsibility. Its often best to assert that the one expected output was produced, rather than asserting that one of countless unexpected outputs wasnt produced.

Equal asserts that the target is strictly (===) equal to the given val.

expect(2).to.equal(2); // Recommended
expect(2).to.not.equal(1); // Not recommended

Ok, now, in the case you may want to add .deep earlier in the chain to use deep equality instead:

// Target object deeply (but not strictly) equals `{a: 1}`
expect({a: 1}).to.deep.equal({a: 1});
expect({a: 1}).to.not.equal({a: 1});

// Target array deeply (but not strictly) equals `[1, 2]`
expect([1, 2]).to.deep.equal([1, 2]);
expect([1, 2]).to.not.equal([1, 2]);

Explaining why is easy:

1 === 1 // These are primitives, they hold the same reference - they are strictly equal
1 == ‘1’ // These are two different primitives, through type coercion they hold the same value - they are loosely equal
{ a: 1 } !== { a: 1 } // These are two different objects, they hold different references and so are not strictly equal - even though they hold the same values inside
{ a: 1 } != { a: 1 } // They have the same type, meaning loose equality performs the same check as strict equality - they are still not equal.

Chai “to.equal” use “deep-eql” algorithm => package.

var deepEql = require(“deep-eql”);
deepEql({ a: 1 }, { a: 1 }) === true // deepEql can determine that they share the same keys and those keys share the same values, therefore they are deeply equal!

Do you want to know more about chai methods? Their docs are amazing.

[Vue.js] Nuxt How to execute external script after rerender only? Subscribe to RSS

Nuxt/Vue: How to call an external script (hosted by a third party) after and only after the DOM has rerendered? On every route.

I’m using a script that adds elements to the dom, but the virtual dom doesn’t match. So, once the script has added the elements, the virtual dom removes them all.

Adding a defer tag doesn’t do anything, it just loads the script after the initial render, then the same thing happens with the rerender.

Presumably this problem is common using frameworks like this.

No errors messages just a single flash of dom elements before rerender. This is the expected behavior with my current set up, but I’m looking (desperate) for a work around.

Solution :

First, you would make a plugin:

export default ({ app: { head, router, context } }, inject) => {
head.scripts.push({
src: ‘http(s)://example.com/script.js’
async: false,
defer: true
})
})

Then you would add the plugin to the nuxt.config.js in the plugins: [] section:

plugins: [
// ….
{ src: ‘~/plugins/script-injecter.js’, ssr: false }
]

Now it will only be provided on page load, and with async: false and defer: true, it will only be executed once the page has finished loading.

[Vue.js] Problem with Cesium integration in OpenLayers 5 - Cesium is not defined Subscribe to RSS

One quick question regarding ol-Cesium. I’m trying to integrate ol-Cesium into my vue.js - Openlayers app. But I’m getting this type of error:

“ReferenceError: Cesium is not defined”

Basically what I’m trying is to activate 3d functionality on click but I’m stuck with error above.

I literally used code provided in examples

import OLCesium from ‘olcs/OLCesium.js’;

const ol3d = new OLCesium({map: this.$store.getters.olMap});
ol3d.setEnabled(true);

I’m using OpenLayers v 5.3.0

Solution :

The error is indicating it’s a webpack error.

I’m referencing documentation found here: https://github.com/gberaudo/ol-cesium-webpack-example/blob/master/webpack.config.js

Make sure you’ve installed Cesium through NPM:

npm i –save-dev cesium olcs copy-webpack-plugin

Then, in the webpack.config.js file, add these lines:

const cesiumSource = ‘node_modules/cesium/Source’;
const cesiumWorkers = ‘../Build/Cesium/Workers’;
const CopywebpackPlugin = require(‘copy-webpack-plugin’);

And in the configuration object of this file, add these lines:

output: {
filename: ‘[name].js’,
path: path.resolve(__dirname, ‘dist’),

// Needed to compile multiline strings in Cesium
sourcePrefix: ‘’
},
amd: {
// Enable webpack-friendly use of require in Cesium
toUrlUndefined: true
},
node: {
// Resolve node module use of fs
fs: ‘empty’
},

Then, add Cesium alias to this file:

resolve: {
alias: {
// CesiumJS module name
cesium: path.resolve(__dirname, cesiumSource)
}
},

Then, add this to plugins in this file:

plugins: [
new HtmlWebpackPlugin({
template: ‘src/index.html’
}),
// Copy Cesium Assets, Widgets, and Workers to a static directory
new CopywebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: ‘Workers’ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Assets’), to: ‘Assets’ } ]),
new CopywebpackPlugin([ { from: path.join(cesiumSource, ‘Widgets’), to: ‘Widgets’ } ]),
new webpack.DefinePlugin({
// Define relative base path in cesium for loading assets
CESIUM_BASE_URL: JSON.stringify(‘’)
})
],

[Vue.js] How can I mimic onbeforeunload in a Vue.js 2 application? Subscribe to RSS

there is a vue.js component that is tracking when it is “dirty” (e.g. unsaved). I would like to warn the user before they browse away from the current form if they have unsaved data. In a typical web application you could use onbeforeunload. I’ve attempted to use it in mounted like this:

mounted: function(){
window.onbeforeunload = function() {
return self.form_dirty ? “If you leave this page you will lose the unsaved changes.” : null;
}
}

However this doesn’t work when using vue.js Router. It will let you navigate down as many router links as you would like. As soon as you try to close the window or navigate to a real link, it will warn you.

Is there a way to replicate onbeforeunload in a vue.js application for normal links as well as router links?

Solution :

Use the beforeRouteLeave in-component guard along with the onbeforeunload event.

The leave guard is usually used to prevent the user from accidentally
leaving the route with unsaved edits. The navigation can be canceled
by calling next(false).

In the component definition do the following:

beforeRouteLeave (to, from, next) {
// If the form is not dirty or the user confirmed they want to lose unsaved changes,
// continue to next view
if (!this.form_dirty || this.confirmLeave()){
next()
} else {
// Cancel navigation
next(false)
}
},

created() {
window.addEventListener(‘beforeunload’, this.onBeforeUnload)
},

beforeDestroy() {
window.removeEventListener(‘beforeunload’, this.onBeforeUnload)
},

methods: {
onBeforeUnload(e) {
if (this.form_dirty && !this.confirmLeave()) {
// Cancel the event
e.preventDefault()
// Chrome requires returnValue to be set
e.returnValue = ‘’
}
},

confirmLeave() {
return window.confirm(‘Do you really want to leave? you have unsaved changes!’)
},
},

there is not tested this and MDN says:

In some browsers, calls to window.alert(), window.confirm(), and
window.prompt() may be ignored during this event. See the HTML
specification for more details.

[Vue.js] What's the easiest way to implement routes in vue.js? Subscribe to RSS

I’m having a hard time understanding how to implemente routes in vue.js using the official guide, is there a way to maybe streamline the process?

Solution :

You can use vue.js router library. Here, components is the folder where vue.js components are added. The variable “path” refers to the url route.

This is a sample router file I created.

import vue.js from “vue”;
import Router from “vue-router”;

Vue.use(Router);

export default new Router({
routes: [
{
path: “/“,
component: () => import(“@/components/Login”),
},
{
path: “/home”,
name : “home”,
component: () => import(“@/components/Home”),
},
]
});

Please refer this document : https://vuejs.org/v2/guide/routing.html

Also, import the router file into app initialisation.

import router from “./router”;

new Vue({
router,
render: h => h(App)
}).$mount(“#app”);

[Vue.js] Firebase Firebase App named '' already exists (app/duplicate-app) Subscribe to RSS

For my Nuxt/Vue.js app I need to export various Firestore-related elements as opposed to just firebase.firestore().

However I’m getting some Firebase App named ‘[DEFAULT]‘ already exists (app/duplicate-app) error for the default export and I don’t understand why:

import firebase from ‘firebase/app’
import ‘firebase/firestore’
const config = {
apiKey: ‘…’,
authDomain: ‘…’,
databaseURL: ‘…’,
projectId: ‘…’,
storageBucket: ‘…’,
messagingSenderId: ‘…’
}
const firebaseApp = firebase.initializeApp(config)
firebase.firestore().settings({ experimentalForceLongPolling: false })
const db = firebase.firestore()
const fb = firebase
export { db, fb }
export default firebaseApp

There is no duplicate that I can identify in this export default line, so what’s wrong?

Solution :

You dont need to export the firebaseApp, this should be good enough

import firebase from ‘firebase/app’
import ‘firebase/firestore’

const config = {
apiKey: ‘…’,
authDomain: ‘…’,
databaseURL: ‘…’,
projectId: ‘…’,
storageBucket: ‘…’,
messagingSenderId: ‘…’
}
if (!firebase.apps.length) {
firebase.initializeApp(config)
}
firebase.firestore().settings({ experimentalForceLongPolling: false })
const db = firebase.firestore()
export { db }
export default firebase

This should avoid calling the instantiation more than once

Solution 2:

The way I handle it is there is a firedb file that I import as needed (throughout the App or just in Vuex). Because the file keeps getting referenced, the config keeps re-loading, which causes the same error.

The way I’ve dealt with it to add this line after the config definition

if (!firebase.apps.length) {
firebase.initializeApp(config);
}

I’ve got an example in condesandbox at https://codesandbox.io/s/vuex-ws-2-60fzg

With the code it would be a little more difficult, since you’re exporting the
firebaseAppconst. But this may work for you (not tested)

import firebase from ‘firebase/app’
import ‘firebase/firestore’
const config = {
apiKey: ‘…’,
authDomain: ‘…’,
databaseURL: ‘…’,
projectId: ‘…’,
storageBucket: ‘…’,
messagingSenderId: ‘…’
}
const firebaseApp = firebase.apps && firebase.apps.length > 0 ? firebase.apps.length[0] : firebase.initializeApp(config)

firebase.firestore().settings({ experimentalForceLongPolling: false })
const db = firebase.firestore()
const fb = firebase
export { db, fb }
export default firebaseApp