link2466 link2467 link2468 link2469 link2470 link2471 link2472 link2473 link2474 link2475 link2476 link2477 link2478 link2479 link2480 link2481 link2482 link2483 link2484 link2485 link2486 link2487 link2488 link2489 link2490 link2491 link2492 link2493 link2494 link2495 link2496 link2497 link2498 link2499 link2500 link2501 link2502 link2503 link2504 link2505 link2506 link2507 link2508 link2509 link2510 link2511 link2512 link2513 link2514 link2515 link2516 link2517 link2518 link2519 link2520 link2521 link2522 link2523 link2524 link2525 link2526 link2527 link2528 link2529 link2530 link2531 link2532 link2533 link2534 link2535 link2536 link2537 link2538 link2539 link2540 link2541 link2542 link2543 link2544 link2545 link2546 link2547 link2548 link2549 link2550 link2551 link2552 link2553 link2554 link2555 link2556 link2557 link2558 link2559 link2560 link2561 link2562 link2563 link2564 link2565 link2566 link2567 link2568 link2569 link2570 link2571 link2572 link2573 link2574 link2575 link2576 link2577 link2578 link2579 link2580 link2581 link2582 link2583 link2584 link2585 link2586 link2587 link2588 link2589 link2590 link2591 link2592 link2593 link2594 link2595 link2596 link2597 link2598 link2599 link2600 link2601 link2602

[Vue.js] Why am I getting an npm missing server error on Vue.js?Explanation

I just installed Node.js and Vue.js and created my first project on vue.js called test . when now trying to set up the server by typing on cmd:

npm run server

But I get the following error:

C:\Users\andri\test>npm run server
npm ERR! missing script: server

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\andri\AppData\Roaming\npm-cache\_logs\2019-02-19T09_12_53_961Z-debug.log

Could anyone help me understand what when missing? I googled a bit around, but have not been able to find a solution so far. I appreciate, any help!

EDIT: This is my package.json file

{
“name”: “test”,
“version”: “0.1.0”,
“private”: true,
“scripts”: {
“serve”: “vue-cli-service serve”,
“build”: “vue-cli-service build”,
“lint”: “vue-cli-service lint”
},
“dependencies”: {
“vue”: “^2.5.22”
},
“devDependencies”: {
“@vue/cli-plugin-babel”: “^3.4.0”,
“@vue/cli-plugin-eslint”: “^3.4.0”,
“@vue/cli-service”: “^3.4.0”,
“babel-eslint”: “^10.0.1”,
“eslint”: “^5.8.0”,
“eslint-plugin-vue”: “^5.0.0”,
“vue-template-compiler”: “^2.5.21”
},
“eslintConfig”: {
“root”: true,
“env”: {
“node”: true
},
“extends”: [
“plugin:vue/essential”,
“eslint:recommended”
],
“rules”: {},
“parserOptions”: {
“parser”: “babel-eslint”
}
},
“postcss”: {
“plugins”: {
“autoprefixer”: {}
}
},
“browserslist”: [
“> 1%”,
“last 2 versions”,
“not ie <= 8”
]
}

Solution :

Replace npm run server with npm run serve

Explanation

In the package.json under the scripts key you don’t have a server script. But you do have a serve one. To run a certain script with npm run it needs to be in scripts inside the package.json

[Vue.js] Remove dynamically created Vue Components

I followed the solution to create dynamic form elements here:
Dynamically adding different components in Vue

Works great, my next conundrum is now to remove form elements if the user adds too many.

The way it works is the user creates a “set” which is defined as a group of inputs. So each set could be for a different person, or place, etc.

Here is my JSfiddle https://jsfiddle.net/61x784uv/

Html

<div id=”component-pii-input” v-for=”field in fields” v-bind:is=”field.type” :key=”field.id”>
</div>
<button id=’button-add-pii-component’ v-on:click=”addFormElement(‘pii-entry-field’)”>Add Set</button>

</div>

Javascript

Vue.component(‘pii-entry-field’, {
data: function () {
return {
fields: [],
count: 0,
}
},
methods: {
addFormElement: function(type) {
this.fields.push({
‘type’: type,
id: this.count++
});
},
},
template: ` <div class=’pii-field’><div>
<component v-for=”field in fields” v-bind:is=”field.type”:key=”field.id”></component>
</div>

<button id=’button-add-pii-input’ v-on:click=”addFormElement(‘pii-input-field’)”>Add Input</button>
<hr>
</div>`,
})

Vue.component(‘pii-input-field’, {
data: function () {
return {

}
},

template: ` <div>
<select>
<option disabled>Select Classification</option>
<option>Name</option>
<option>Address</option>
<option>Email</option>
<option>Phone</option>
<option>Medical</option>
<option>Financial</option>
</select>

<div>
<input type=”text” placeholder=”Input”>
</div>
<button v-on:click=”removeFormElement”>Remove Input</button></span>
</div>`,
})

var app = new Vue({
el: ‘#app’,
data: {
fields: [],
count: 0,
},
methods: {
addFormElement: function(type) {
this.fields.push({
‘type’: type,
id: this.count++
});
},

}
});

Solution :

You should probably move these remove buttons into a <slot> of the component so you could pass in the scoped id.

But if you can’t, you could $emit removal event on the $parent of the individual components, passing the id of the item to remove.

Vue.component(‘pii-entry-field’, {
data() {
return {
fields: [],
count: 0,
}
},

mounted() {
this.$on(‘removeFormElement’, this.removeFormElement);
},

methods: {
addFormElement(type) {
this.fields.push({
‘type’: type,
id: this.count++
});
},

removeFormElement(id) {
const index = this.fields.findIndex(f => f.id === id);

this.fields.splice(index, 1);
}
},

template: `
<div class=’pii-field’>
<component v-for=”field in fields” v-bind:is=”field.type” :key=”field.id”></component>

<button id=’button-add-pii-input’ v-on:click=”addFormElement(‘pii-input-field’)”>Add Input</button>
<hr>
</div>`,
})

Vue.component(‘pii-input-field’, {
data() {
return {

}
},

methods: {
removeFormElement() {
const id = this.$vnode.key;
this.$parent.$emit(‘removeFormElement’, id);
}
},

template: `
<div>
<select>
<option disabled>Select Classification</option>
<option>Name</option>
<option>Address</option>
<option>Email</option>
<option>Phone</option>
<option>Medical</option>
<option>Financial</option>
</select>

<div>
<input type=”text” placeholder=”Input” />
</div>
<button v-on:click=”removeFormElement”>Remove Input</button>
</div>`,
})

var app = new Vue({
el: ‘#app’,

data() {
return {
fields: [],
count: 0,
}
},

methods: {
addFormElement(type) {
this.fields.push({
‘type’: type,
id: this.count++
});
},

}
});
<script src=”https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id=”app”>
<div id=”component-pii-input” v-for=”field in fields” v-bind:is=”field.type” :key=”field.id”>

</div>

<button id=”button-add-pii-component” v-on:click=”addFormElement(‘pii-entry-field’)” class=”uk-button uk-button-primary uk-width-1-1 uk-margin-small”>Add Set</button>
</div>

Solution 2:

Here is a working fiddle: https://jsfiddle.net/e12hbLcr/

Walkthrough:

You need to give the component some kind of id to know what component should be removed. You can do this with props.

<component v-for=”field in fields” v-bind:is=”field.type” :id=”field.id” :key=”field.id”>
Now create the function in the child-component and edit the button so it sends the id.

<button v-on:click=”removeFormElement(id)”>Remove Input&lt/button>

Remember in vue.js that props go down (parent -> child) and events up (child-parent). So now we need to tell the parent that this button was clicked and an id was sent.

removeFormElement(id) {
console.log(‘sending message up to remove id’, id)
this.$emit(‘remove’, id)
}

Tell the parent component to listen to that event and attach a function to that event.

<component v-for=”field in fields” v-bind:is=”field.type” :id=”field.id” @remove=”removeFormElement” :key=”field.id”>

Note that the @ is same as v-on:

Finally remove that item from the fields array.

removeFormElement(id) {
console.log(‘removing form element’, id)
const index = this.fields.findIndex(f => f.id === id)
this.fields.splice(index,1)
}

[Vue.js] Console warning component lists rendered with v-for should have explicit keys

I got a problem here, I don’t know what is wrong in my code, but I got a warning in my console, how can I remove this warning?

[vue.js tip]: <todo-item v-for=”todoItem in todos”>: component lists rendered with v-for should have explicit keys. See https://vuejs.org/v2/guide/list.html#key for more info.
(found in <Root>)

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8”>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0”>
<title>vue.js Tutorial</title>
<link rel=”shortcut icon” href=”https://vuejs.org/images/logo.png">
<script src=”scripts/vue.js”></script>
</head>
<body>
<section id=”app”>
<p>{ msg }</p>
<p v-bind:title=”message”>
Hover the mouse over me for a few seconds to see my dynamically bound title!
</p>
<div>
<p v-if=”seen”>This text will show or hide if the button was clicked.</p>
<button type=”button” v-on:click=”isSeen”>{ isSeenText }</button>
</div>
<ol>
<li v-for=”todo in todos”>
{ todo.text }
</li>
</ol>
<p>Total count: { todos.length }</p>
<div v-bind:title=”reverseMessageText”>
<p>{ reverseMessageText }</p>
<button v-on:click=”reverseMessage”>Reverse Message</button>
</div>
<div>
<p>Data binding: <strong>{ nameOfUser }</strong></p>
<input type=”text” v-model=”nameOfUser”>
</div>
<div>
<ol>
<todo-item v-for=”todoItem in todos” v-bind:data=”todoItem”></todo-item>
</ol>
</div>
</section>
<script src=”scripts/app.js”></script>
</body>
</html>

app.js

var appComponent = Vue.component(‘todo-item’, {
template: ‘<li>id: { data.id }<br>text: { data.text }</li>’,
props: [
‘data’
]
});

new Vue({
el: ‘#app’,
data: {
msg: ‘Hello World!’,
message: ‘You loaded this page on ‘ + new Date(),
seen: true,
isSeenText: ‘Now you don\‘t’,
todos: [
{
text: ‘Learn JavaScript’
},
{
text: ‘Learn Vue’
},
{
text: ‘Build something awesome’
}
],
reverseMessageText: ‘Hello World from Vue.js!’,
nameOfUser: ‘John Rey’
},
methods: {
reverseMessage: function() {
this.reverseMessageText = this.reverseMessageText.split(‘’).reverse().join(‘’);
},
isSeen: function() {
this.seen = !this.seen;
this.isSeenText = this.seen ? ‘Now you don\‘t’ : ‘Now you see me’;
}
}
});

console.log

Here is the link that vue.js suggested here. I think i don’t have any error, to solve that warning but I cannot find where’s the cause, btw I’m newbie here to Vue.

Solution :

The answer is listed explicitly in the documentation you linked…

<todo-item v-for=”todoItem in todos”
v-bind:data=”todoItem”
v-bind:key=”todoItem.text”></todo-item>

To summarise some information from the comments below… you use :key to let the component know how to identify individual elements. This allows it to keep track of changes for Vue’s reactivity.

It’s best to try and bind the :key to some uniquely identifying property of each item. For example, an id.

Solution 2:

My solution to a similar problem looked like this:

- <el-radio v-for=”option in field.options”> …
+ <el-radio v-for=”(option, index) in field.options” :key=”index”> …

Or using v-bind syntax for index:

+ <el-radio v-for=”(option, index) in field.options” v-bind:key=”index”> …

[Vue.js] javascript - In an array of objects, returns objects where ANY value matches a specific string

I’m implementing search functionality into my application. The search results in the UI are returned based on an array of objects. Essentially what I’m trying to do is iterate over the name, custNumber, and sneak values in each object, and only return the objects that contain a value that includes a string (generated from the users search bar). The idea is that users can search for anything in the object and yield the correct results

here is my array

var result = [{
name: ‘Donna Shomaker’,
custNumber: ‘6658924351’,
sneak: ‘string1 string1 string1’,
foo: false,
bar: false,
},
{
name: ‘Ron Duluth’,
custNumber: ‘8812654434’,
sneak: ‘string2 string2 string2’,
foo: false,
bar: false,
},
{
name: ‘Jimmy Dawson’,
custNumber: ‘8908198230’,
sneak: ‘string3 string3 string3’,
foo: false,
bar: false,
}
]

This is how far I’ve gotten

return result.filter(convo => {
return convo.name.toLowerCase().includes(searchbarVal.toLowerCase())
})

The obvious problem here is that this only is only returning objects based on the name value. However, I need it to compare the name, custNumber, and sneak values in each object to the users search. I’ve tried forEach, object.values, and object.entries methods and haven’t been able to get them to work. Any help here is much appreciated!!

Solution :

recursive search

This is a topic I’ve written about recently. Here is a generic deepFind. It works recursively and accepts can “search” any input value.

Below we construct a simple set of data and then show how deepFind can search the data and return matches

const data =
[ { a: 1, b: 1 }
, { a: 2, b: 2, c: { d: [ { e: 2 } ] } }
, { a: 3, b: { c: { d: { e: { f: 3 } } } } }
]

const deepFind = (f, obj = {}) =>
{ if (Object (obj) === obj)
{ if (f (obj) === true)
return obj

for (const [ k, v ] of Object.entries (obj))
{ const res =
deepFind (f, v)

if (res !== undefined)
return res
}
}

return undefined
}

console.log
( deepFind (x => x.a === 1, data) // { a: 1, b: 1 }
, deepFind (x => x.e === 2, data) // { e: 2 }
, deepFind (x => Array.isArray(x.d), data) // { d: [ { e: 2 } ] }
, deepFind (x => x.f === 3, data) // { f: 3 }
, deepFind (x => x.e && x.e.f === 3, data) // { e: { f: 3 } }
, deepFind (x => x.z === 9, data) // undefined
)

Above deepFind only works by matching values directly using ===. Because it accepts a higher-order function f however, we can specialize its behavior in meaningful ways.

string match using deepFind

Below we encode our generic string-matching search function using deepFind

const search = (query = “”, data) =>
deepFind
( o =>
Object.values (o) .some (v =>
String (v) === v && v .includes (query))
, data
)

search (“D”, result)
// { name: “Donna Shomaker”, … }

search (“Du”, result)
// { name: “Ron Duluth”, … }

search (“ng3”, result)
// { name: “Jimmy Dawson”, sneak: “string3 string3 string3”, … }

search (“zzz”, result)
// undefined

Verify the results in the own browser

const deepFind = (f, obj = {}) =>
{ if (Object (obj) === obj)
{ if (f (obj) === true)
return obj

for (const [ k, v ] of Object.entries (obj))
{ const res =
deepFind (f, v)

if (res !== undefined)
return res
}
}

return undefined
}

const search = (query = “”, data) =>
deepFind
( o =>
Object.values (o) .some (v =>
String (v) === v && v .includes (query))
, data
)

const result =
[ { name: ‘Donna Shomaker’
, custNumber: ‘6658924351’
, sneak: ‘string1 string1 string1’
, foo: false
, bar: false
}
, { name: ‘Ron Duluth’
, custNumber: ‘8812654434’
, sneak: ‘string2 string2 string2’
, foo: false
, bar: false
}
, { name: ‘Jimmy Dawson’
, custNumber: ‘8908198230’
, sneak: ‘string3 string3 string3’
, foo: false
, bar: false
}
]

console.log (search (“D”, result))
// { name: “Donna Shomaker”, … }

console.log (search (“Du”, result))
// { name: “Ron Duluth”, … }

console.log (search (“ng3”, result))
// { name: “Jimmy Dawson”, sneak: “string3 string3 string3”, … }

console.log (search (“zzz”, result))
// undefined

returning multiple search results

The program above only returns the first match. If you wanted to return all of the results, we can do so using generators, which are perfectly suited for this task

const deepFindAll = function* (f, o = {})
{ if (Object (o) === o)
{ if (f (o) === true)
yield o
for (const [ _, v ] of Object.entries (o))
yield* deepFindAll (f, v)
}
}

Now we implement searchAll using our new generator

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( o =>
Object.values (o) .some (v =>
String (v) === v && v .includes (query))
, data
)
)

searchAll (“81”, result)
// [ { custNumber: ‘8812654434’, … }
// , { custNumber: ‘8908198230’, … }
// ]

searchAll (“Du”, result)
// [ { name: “Ron Duluth”, … } ]

searchAll (“zzz”, result)
// []

Run searchAll in the browser below

const deepFindAll = function* (f, o = {})
{ if (Object (o) === o)
{ if (f (o) === true)
yield o
for (const [ _, v ] of Object.entries (o))
yield* deepFindAll (f, v)
}
}

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( o =>
Object.values (o) .some (v =>
String (v) === v && v .includes (query))
, data
)
)

const result =
[ { name: ‘Donna Shomaker’
, custNumber: ‘6658924351’
, sneak: ‘string1 string1 string1’
, foo: false
, bar: false
}
, { name: ‘Ron Duluth’
, custNumber: ‘8812654434’
, sneak: ‘string2 string2 string2’
, foo: false
, bar: false
}
, { name: ‘Jimmy Dawson’
, custNumber: ‘8908198230’
, sneak: ‘string3 string3 string3’
, foo: false
, bar: false
}
]

console.log (searchAll (“81”, result))
// [ { custNumber: ‘8812654434’, … }
// , { custNumber: ‘8908198230’, … }
// ]

console.log (searchAll (“Du”, result))
// [ { name: “Ron Duluth”, … } ]

console.log (searchAll (“zzz”, result))
// []

case insensitive search

Above, our search function uses v .includes (query) but because we’re working with a higher-order function, we can make the behaviour as specific as we want.

Using searchAll as an example, we could change it like below

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( o =>
Object.values (o) .some (v =>
String (v) === v && v .includes (query))
String (v) === v
&& v .toLowerCase () .includes (query .toLowerCase ()))
, data
)
)

But that’s making a complete mess of our function. It’s time to abstract a little more and explain what we’re doing by giving our intentions names

const anyString = f => o =>
Object.values (o) .some (v =>
String (v) === v && f (v))

const caseInsenstiveMatch = (x, y) =>
x.toLowerCase () .includes (y.toLowerCase ())

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( anyString (v =>
caseInsenstiveMatch (v, query))
, data
)
)

Isolating behaviors and defining separate functions is an important part of writing good programs. Showing search and searchAll side-by-side highlights this importance. The new helpers anyString and caseInsensitiveSearch keep the code clear, but also make it easier to reuse behaviours where needed.

const search = (query = “”, data) =>
deepFind
( anyString (v =>
caseInsenstiveMatch (v, query))
, data
)

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( anyString (v =>
caseInsenstiveMatch (v, query))
, data
)
)

contramap

Higher-order functions have all sorts of uses for keeping our code clean and descriptive. Below, we define dead-simple versions of match and lower. Then using contramap, we bring our program together.

The emphasis here is on the simplicity of each function. A simple function is easier to test, easier to debug, and easier to combine with other simple functions. The Unix philosophy, “Do one thing and do it well” should be ringing in the ears right now

const contramap = (f, g) =>
(x, y) => f (g (x), g (y))

const match = (x = “”, y = “”) =>
x .includes (y)

const lower = (x = “”) =>
x .toLowerCase ()

const caseInsenstiveMatch =
contramap (match, lower)

const anyString = (f) => (o = {}) =>
Object.values (o) .some (v =>
String (v) === v && f (v))

const searchAll = (query = “”, data = {}) =>
Array.from
( deepFindAll
( anyString (v =>
caseInsenstiveMatch (v, query))
, data
)
)

Contramap unlocks other powers that may not be immediately obvious. If it interests you, I recommend Monoidal Contravariant Functors are actually useful! by Brian Lonsdorf. Don’t let the title scare you; the author has a knack for making this stuff easy.

Solution 2:

A ‘some’ in the filter might do the trick, checking all the keys.

return result.filter(convo => {
return Object.keys(convo).some(key => {
return convo[key].toLowerCase().includes(searchbarVal.toLowerCase())
})
})

Solution 3:

function searchObj(search){
let answer = [];
result.forEach(re => {
if(JSON.stringify(re).indexOf(search) > 0){
answer.push(re)
}
});
return answer;
}

Loop through every element of the array, convert them into a string and use indexOf to find the matching criteria. That way you can save a few loops without looping each and every key of every element.

Solution 4:

Try

let search= result.filter(x=> [‘name’,’custNumber’,’sneak’]
.reduce((o,a)=> x[a].toLowerCase().includes(query.toLowerCase())||o, false) );

Where query is the searchbarVal.toLowerCase()

var result = [{
name: ‘Donna Shomaker’,
custNumber: ‘6658924351’,
sneak: ‘string1 string1 string1’,
foo: false,
bar: false,
},
{
name: ‘Ron Duluth’,
custNumber: ‘8812654434’,
sneak: ‘string2 string2 string2’,
foo: false,
bar: false,
},
{
name: ‘Jimmy Dawson’,
custNumber: ‘8908198230’,
sneak: ‘string3 string3 string3’,
foo: false,
bar: false,
}
]

let query=”89”; // searchbarVal.toLowerCase()

let search= result.filter(x=> [‘name’,’custNumber’,’sneak’].reduce((o,a)=> x[a].toLowerCase().includes(query.toLowerCase())||o, false) );

console.log(search);

Solution 5:

You can loop through the object and try and do something like the following:

var result = [{
name: ‘Donna Shomaker’,
custNumber: ‘6658924351’,
sneak: ‘string1 string1 string1’,
foo: false,
bar: false,
},
{
name: ‘Ron Duluth’,
custNumber: ‘8812654434’,
sneak: ‘string2 string2 string2’,
foo: false,
bar: false,
},
{
name: ‘Jimmy Dawson’,
custNumber: ‘8908198230’,
sneak: ‘string3 string3 string3’,
foo: false,
bar: false,
}
];

var searchStr = “Donna”;

console.log(searchObj(searchStr));

function searchObj(search){
var searchResult = [];
for(var obj in result){
var str = JSON.stringify(result[obj]);
if(str.indexOf(search) > 0){
searchResult.push(result[obj]);
}
}
return searchResult;
}

[Vue.js] Handle Vue render errors locally

when using vue.js (server side rendered) with mjml to generate emails.

So there is something (overly simplified) like:

<mjml><mj-body>Hello { User.Name }</mj-body></mjml>

If the model doesn’t define User then vue.js throws an error and the whole output is lost.

What to the output to be along the lines:

<mjml><mj-body>Hello <error>’User’ is undefined</error></mj-body></mjml>

there is implemented Vue.config.errorHandler but that just tells me about the error — there is no rendered output.

Anyway to implement the equivalent of an error handler around each variable substitution?

Solution :

If you are using vue.js version >= 2.5, you can use errorCaptured to create an ErrorBoundary

const ErrorBoundary = {
name: ‘ErrorBoundary’,
data: () => ({
error: false,
msg: ‘’
}),
errorCaptured (err, vm, info) {
this.error = true
this.msg = `${err.stack}\n\nfound in ${info} of component`
},
render (h) {
return this.error
? h(‘pre’, this.msg)
: this.$slots.default[0]
}
}

and use this in the component

<error-boundary>
<mjml><mj-body>Hello { User.Name }</mj-body></mjml>
</error-boundary>

If the application has any javascript error, it will be displayed on UI

Example on codepen

If you want to have more user-friendly error, you can customize ErrorBoundary to have fallback to another component. You can find out in this tutorial

Another good example of using errorHandler

[Vue.js] Cannot find example how to use gradient while using vuex and reactiveProps mixin (API Data)

Problem

Codepen: https://codesandbox.io/s/vyy0z2my33

First, you can keep track this problem on: https://github.com/apertureless/vue-chartjs/issues/473
Also there is a project using datepicker which rerenders the chart based on given date thus if you look on the codepen, at the BarChart.vue, you can see I add watcher to rerender the chart

But turned out got error when every time I select a date

Background

In a nutshell, I can’t find the example how to put the gradient to the chart.

Code

BarChart.vue

<script>
import { Bar, mixins } from “vue-chartjs”;
import { mapGetters } from “vuex”;

export default {
extends: Bar,
mixins: [mixins.reactiveProp],
props: [“chartData”, “chartLabels”, “options”],

mounted() {
// chartData is created in the mixin
// let gradientFill = this.$refs.canvas.getContext(‘2d’).createLinearGradient(2000, 0, 0, 0);

// gradientFill.addColorStop(0, “#18FFFF”);
// gradientFill.addColorStop(1, “#FF1744”);
this.renderChart(
{
labels: this.chartLabels,
datasets: [
{
data: this.chartData,
backgroundColor: “red”,
hoverBackgroundColor: “red”
}
]
},
this.options
);
},
computed: {
…mapGetters([“getBarHourTooltip”])
},
watch: {
chartData() {
this.$data._chart.update();
},
chartLabel() {
this.$data._chart.update();
}
}
};
</script>

Actual Result

Can’t implement the gradient color
Data’s well shown on initial, but got error when a date selected (as shown on image above)

Solution :

I was not able to reproduce with the codesandbox project. How are you changing the date?

The error message is referring to a map() method used on an undefined array, presumably originating in src/store/stores.js. You could try to wrap the offending map() method call in a control statement, like this:

if (payloadInitAllChart.barDataHour) { // Example, could be other map() method
payloadInitAllChart.barDataHour.map(response =>
state.barChartPerHour.datasetBarHour.push(response)
);
}

[Vue.js] How to add the value of an input to a li list?

when trying to add the value of an input as a <li> to a <ul> list.

I was able to add it by binding the value to the array list of lis. However, it doesn’t stay there when I clean the input field. How can I fix this?

HTML code:

<div id=”app”>
<h1>{ message }</h1>
<form v-on:submit.prevent=”addNewTodo”>
<input type=”text” v-model=”todo.task”>
<button type=”submit”>Add todo</button>
</form>

<ul>
<li v-for=”todo in todos” :class=”{ completed: todo.isActive }” @click=”$set(todo, ‘isActive’, !todo.isActive)”>
{ todo.task } <span v-on:click=”deleteTodo”>{ todo.delete }</span>
</li>
</ul>
</div>

JS Code:

var app = new Vue({
el: ‘#app’,
data: {
message: ‘List of things to do today’,
todos: [
{ task: ‘Have breakfast’, delete:’(x)’},
{ task: ‘Go to the gym’, delete:’(x)’},
{ task: ‘Study Vuejs’, delete:’(x)’}
],
todo: {task: ‘’, delete: ‘(x)’}
},
methods: {
addNewTodo: function(){
this.todos.push( this.todo );
},
deleteTodo: function(){
this.todos.shift( this.todo )
},
}
});

Here there is a sample JSfiddle: https://jsfiddle.net/mercenariomode/gwd34815/1/

Solution :

You need to change the object reference, but in the case, it would be better to bind the “v-model” to the “task” property

Html code:

<form v-on:submit.prevent=”addNewTodo”>
<input type=”text” v-model=”task”>
<button type=”submit”>Add todo</button>
</form>

JS Code:

el: ‘#app’,
data: {
message: ‘List of things to do today’,
todos: [
{ task: ‘Have breakfast’, delete:’(x)’},
{ task: ‘Go to the gym’, delete:’(x)’},
{ task: ‘Study Vuejs’, delete:’(x)’}
],
task: ‘’,
}

and in the addNewTodo method implement the logic of adding an object to the array

addNewTodo: function(){
let todo = {task: this.task, delete: ‘(x)’};
this.todos.push(todo);

this.task = ‘’; // clear data in input
},

JSFiddle: https://jsfiddle.net/nm29yq7d/1/

Solution 2:

You’re always referencing that property, you should clone it properly like :

let t={};
Object.assign(t,this.todo)
this.todos.push( t );

Another issue that i see in the code is you’re deleting the wrong todo, to fix that just pass the index of the selected todo to the deleteTodo method as follows :

<ul>
<li v-for=”(todo,i) in todos” :class=”{ completed: todo.isActive }” @click=”$set(todo, ‘isActive’, !todo.isActive)”>
{ todo.task } <span v-on:click=”deleteTodo(i)”>{ todo.delete }</span>
</li>
</ul>

and use this.todos.splice(i,1); to delete the given todo :

deleteTodo: function(){
this.todos.splice(i,1);
}

[Vue.js] Error 422 Unprocessable Entity - Rails API VueJS From

I’m trying to create a new user through a vuejs form. I’m using a Rails API for the backend.

I’m using gem knock and gem bcrypt for JWT authorisation.

When I submit the form, when getting a 422 error in the terminal. Something I’ve noticed is that it looks like it’s trying to process this as HTML, and not json.

Started POST “/api/v1/users” for 127.0.0.1 at 2019-02-17 21:18:05 +0000
Processing by Api::V1::UsersController#create as HTML
Parameters: {“email”=>”ui@gmail.com“, “password”=>”[FILTERED]“, “user”=>{“email”=>”ui@gmail.com“}
Completed 422 Unprocessable Entity in 10ms (Views: 0.9ms | ActiveRecord: 0.0ms | Allocations: 576)

When using Insomnia, I’m able to create new user perfectly fine, which is leading me to focus on the frontend being the problem.

Further, when I remove has_secure_password from the user model, the form submits with succeeded 200, albeit without a password.

So why is the password playing up here?

createuser.vue

<template>
<div class=”card-container”>
<div class=”signup”>
<form @submit.stop.prevent=”newUser”>
<input id=”email” v-model=”email” type =”text” name=”email” class=”input”>
<input id=”password” v-model=”password” type=”password” name=”password” class=”input”>
<input type=”submit” value=”Submit” class=”btn-update”>
</form>
</div>
</div>
</template>
<script>
import axios from ‘axios’
export default {
data() {
return {
email: ‘’,
password: ‘’,
errors: []
}
},

methods: {

newUser() {
axios.post(‘http://localhost:3001/api/v1/users', {
email: this.email,
password: this.password
})
.then(res => (this.user = res.data))
.catch((error) => {
console.log(error)
});
},
}
};

</script>
<style>

</style>

routes.rb

Rails.application.routes.draw do

namespace :api do
namespace :v1 do
post ‘user_token’ => ‘user_token#create’
resources :users
resources :posts

#post ‘/users/create’ => ‘users#create’ not making a difference

#get ‘/users/current’ => ‘users#current’
end
end
end

users_controller.rb

class Api::V1::UsersController < ApplicationController
before_action :authenticate_user, only: [:index, :current, :update]

def index
render json: User.all, status: 200
end

# Call this method to check if the user is logged-in.
# If the user is logged-in we will return the user’s information.
def current
current_user.update!(last_login: Time.now)
render json: current_user
end

#def show
# @user = User.find(params[:id])

# render json: User.find(params[:id]), status: 200

#end

def create
user = User.new(user_params)

if user.save
render json: user, status: :created, location: user
else
render json: user.errors, status: :unprocessable_entity
end
end

def update
if @user.update(user_params)
render :show, status: :ok, location: @user
else
render json: @user.errors, status: :unprocessable_entity
end
end

def destroy
@user.destroy
end

private
def set_user
@user = User.find(params[:id])
end

def user_params
params.require(:user).permit(:email, :password, :avatar)
end
end

UPDATE

I’ve added a default option to the API namespace.
namespace :api, defaults: {format: :json}

This has ‘corrected’ the processing as JSON:

Processing by Api::V1::UsersController#create as JSON

But I still get 422 Code.

Solution :

You need to wrap post data in user object

{
“user”:
{
“email”: “user@example.com“,
“password”: “password”
}
}

You can change the request

axios.post(‘http://localhost:3001/api/v1/users', {
user: {
email: this.email,
password: this.password
}
})
.then(res => (this.user = res.data))
.catch((error) => {
console.log(error)
});

[Vue.js] Adding form elements(time slot) dynamically as per selected day in vue js

when new in vue.js js development. there is one form which includes days list. If i select monday it will show text field to add time slot for monday and there is one button “Add more” to add more time slots day wise. when trying to add time slots day-wise but currently what is happening if I add time slot then it shows in all days.
Js fiddle - https://jsfiddle.net/1rgc6x04/3/
Here is what there is done so far -

<template>
<div>
<div class=”box-with-radius margin-top-30 clearfix”>
<div class=”col-sm-12” v-for=”(dayVal,index) in days”>
<div class=”checkbox”>
<input :id=”‘day’+dayVal.id” type=”checkbox” @change=”manageTiming(dayVal.id,dayVal.day,$event)” :value=”dayVal.day” v-model=”timeData” />
<label :for=”‘day’+dayVal.id” :checked=”dayVal.status”>{dayVal.day}</label>
<div class=”space”></div>
</div>
<div class=”container” id=”app-container” v-show=”dayVal.status”>
<div class=”row” v-for=”find in finds”>
<div class=”time-slot”>
<div class=”col-sm-9 col-md-4”>
<label for=”chkTest”>Time</label>
<input type=”text” name=”start-time” class=”form-control form-input start-time” v-model=”find.value”>
</div>
<div class=”col-sm-3 col-md-4”>
<button class=”delete-button”>
<i class=”fa fa-trash” aria-hidden=”true”></i>
</button>
</div>
</div>
</div>
<div class=”col-sm-12”>
<button class=”add-more-time-slot” type=”button” @click=”btnAddMore”>
ADD MORE TIME SLOT
</button>
</div>
</div>
</div>

<div class=”form-group”>
<div class=”row”>
<div class=”col-sm-4”>
<button class=”btn btn-save” type=”submit”>SAVE</button>
</div>
</div>
</div>
</div>
</div>
<template>

<script>
import Doctorheader from ‘../../../components/layout/Doctorheader’;
import ‘vue-country-region-select’

export default {
name: ‘Profile’,
components : {
‘doctorheader-component’ : Doctorheader
},
data () {
return {
days : [
{id : 1,day : ‘MONDAY’,status : false},
{id : 2,day : ‘TUESDAY’,status : false},
{id : 3,day : ‘WEDNESDAY’,status : false},
{id : 4,day : ‘THURSDAY’,status : false},
{id : 5,day : ‘FRIDAY’,status : false},
{id : 6,day : ‘SATURDAY’,status : false},
{id : 7,day : ‘SUNDAY’,status : false}
],
finds : []
}
},
methods : {
btnAddMore(){
this.finds.push({ days: ‘’ });
}
}
}
</script>

How to add time slots as per day?
Any help would be appreciated.
Thanks

Solution :

Fiddle should be as short as possible. So I removed some unused vars :)
ids on nodes if v-for - is bad. Removed
manageTiming is unnecessary - you can mutate data directly from template. It is ok, but I refactored this place
If it is possible to store finds in days here is a working example:

https://jsfiddle.net/cmjt5fpb/1/

<div class=”row” v-for=”time, idx in dayVal.times”>
<div class=”time-slot”>
<div class=”col-sm-9 col-md-4”>
<label for=”chkTest”>Time</label>
<input type=”text” name=”start-time” class=”form-control form-input start-time” v-model=”dayVal.times[idx]“>
</div>
</div>
</div>

[Vue.js] Vue async component callback

<template>
<div>
<AsyncComponent1></AsyncComponent1>
<!– Render AsyncComponent2 after AsyncComponent1 –>
<AsyncComponent2></AsyncComponent2>
</div>
</template>

<script>
export default {
name: “My Component”
components: {
AsyncComponent1: () => import(“./AsyncComponent1”),
AsyncComponent2: () => import(“./AsyncComponent2”)
}
};
</script>

I’m loading two components asynchronously within a component but I need one of the components to render after the other. I wonder if thats possible?

Solution :

You could have the first component emit an event, that is listened to by the parent and used to toggle the second component

<template>
<div>
<AsyncComponent1 v-on:loaded=”componentLoaded”></AsyncComponent1>
<!– Render AsyncComponent2 after AsyncComponent1 –>
<AsyncComponent2 v-if=”hasComponent”></AsyncComponent2>
</div>
</template>

<script>
export default {
name: “My Component”,
components: {
AsyncComponent1: () => import(“./AsyncComponent1”),
AsyncComponent2: () => import(“./AsyncComponent2”)
},
data: {
hasComponent: false
},
methods: {
componentLoaded() {
this.hasComponent = true;
}
}
};
</script>

And then in AsyncComponent1.vue:


mounted() {
this.$emit(“loaded”);
}

Solution 2:

Add a v-if to a ref in the other component.

<template>
<div>
<AsyncComponent1 ref=”c1”></AsyncComponent1>
<!– Render AsyncComponent2 after AsyncComponent1 –>
<AsyncComponent2 v-if=”$refs.c1”></AsyncComponent2>
</div>
</template>