Software
Splice out this.index from array between components in VueJS
I have an array of quotes in my parent template which I pass to a child component as a prop. I then take that array and create another child component for each index in the array by passing it through a for loop into a slot. This all seems to work fine.
The problem is that I am trying to delete each index of the array on clicking it's element, but whenever I click an element the first index is deleted, not the index linked to the element clicked.
In the following component I execute method @click and run the method deleteQuote passing the related index.
<template> <div class="panel-body" @click="deleteQuote"> <slot></slot> </div> </template> <script type="text/javascript"> export default{ methods: { deleteQuote() { this.$emit('deleteThisQuote', this.index) } }, props: ['index'] } </script>Since this component doesn't have direct access to my array, I emit a custom event that is listened for in its parent. This triggers another method which splices my array at this.index. Following is the parent component...
<template> <div> <quote-singles class="col-sm-3 panel panel-default" v-for="(quote, index) in quotes" :index="index" @deleteThisQuote="deleteQuote($event)"><h3>{{index}}{{quote}}</h3> </quote-singles> </div> </template> <script type="text/javascript"> import quoteSingles from './quoteSingles.vue' export default{ methods: { deleteQuote(event) { this.quotes.splice(this.event, 1); } }, props: ['quotes'], components: { 'quoteSingles': quoteSingles } } </script>This does everything I want, except it splices out the wrong index in the array. No matter which element I click, myArray[0] is removed. What is going on here? Am i missing something elementary?
Vue.js Webpack dynamic components error during compiling
I am compiling a Vue script with webpack. I am testing dynamic components loading asynchronously, but I get an error during compiling.
Vue.component( 'login-form', () => import('./async v-components/login-form') );I get: Syntax Error: Unexpected token (22:10) pointing to 'i' of 'import'.
webpack.mix.js:
mix.js('resources/assets/js/frontApps.js', 'public/js').extract(['vue']);Any idea why this simple example fails? I followed the guide precisly.
router-link and href not working in Vue js
I am learning vue js and i created an admin page which i am able to route when i am using router-view but when i am trying href or router-link i am not able to load the template thought the url gets changed.
this is my main.js
import Vue from 'vue' import VueResource from 'vue-resource' import VueRouter from 'vue-router' import App from './App.vue' import admin from "./components/admin/admin.vue" import users from "./components/users.vue" Vue.use(VueRouter); Vue.use(VueResource); const router = new VueRouter({ routes: [ {path:'/admin',component:admin}, {path:'/users',component:users}, ] }) new Vue({ el: '#app', router: router, render: h => h(App) })this is my app.vue
this is my app vue file which just want to route to a page via href
<template> <div class = "container" id="app"> <h1>Hi from</h1> <hr> <a href="/api/users">sdsd</a> </div> </template> <script> export default { name: 'app', data(){ return{ users: "" } } } </script> <style> #app { } </style>this is my admin.vue
this the template i want to load in my app.vue its a simple template i want to display in app.vue. its somehow working router-view but it is not working with router-link
<template> <div class="container"> <h1> HI i am routing from admin </h1> </div> </template>the above thing is working via router-view but not thing router-link or href anchor tags............................................................................................................................................................................................
How to edit and update form input values in vue.js?
I am getting up the details in a form for a hotel entry with basic details and viewing it in Room.vue. The created values were displayed here but here i need to give edit option for the filled details. When i click the edit, the page should redirect to RoomsEdit.vue and i should get the filled up contents in that page with form inputs. For that i have tried the following codes but nothing solves my issue.. Kindly have a go through and help me in solving the issue.
Room.vue:
<table class="table table-striped table-hover rooms-table"> <thead> <tr> <td>Title<i class="fa fa-sort"></i></td> <td>Sub Title<i class="fa fa-sort"></i></td> <td> Edit </td> <td> Delete </td> </tr> </thead> <tbody> <tr v-for="room in items"> <td>{{ room.title }}</td> <td>{{ room.subtitle }}</td> <td> <router-link class="btn btn-primary" v-bind:to="'rooms/edit/'+id">Edit</router-link> </td> <td> <button class="btn btn-primary" v-on:click="deleteRoom(room)">Delete</button> </td> </tr> </tbody> </table>Here i am giving edit option and making a redirect to edit page..
RoomsEdit.vue:
<form @submit.prevent="updateItems" class="form-horizontal" enctype="multipart/form-data"> <div class="form-group"> <label for="title" class="col-sm-2 control-label">Title<span class="red">*</span></label> <div class="col-sm-6"> <input type="text" name="title" class="form-control" id="title" v-model="itemsData.title"> <span class="text-danger">{{ errors.title?errors.title[0]:"" }}</span> </div> </div> <div class="form-group"> <label for="subtitle" class="col-sm-2 control-label">Subtitle<span class="red">*</span></label> <div class="col-sm-6"> <input type="text" name="subtitle" class="form-control" id="subtitle" v-model="itemsData.subtitle"> <span class="text-danger">{{ errors.subtitle?errors.subtitle[0]:"" }}</span> </div> </div> </form>Script of RoomsEdit:
<script> import config from '../../../config'; export default { data(){ return{ items: [], itemsData:{ title : '', subtitle : '', }, errors: { } } }, methods:{ fetchRoom(id){ axios.get(config.apiDomain+'/Rooms').then((response)=>this.items = response.data); }, updateItems(e){ axios.put(config.apiDomain+'/Rooms/edit'+this.$route.params.id,this.itemsData).then(response=>{ this.this.itemsData = ""; this.$router.push('/admin/rooms'); }).catch(error=>{ this.errors = error.response.data; }); } }, created: function() { this.fetchRoom(this.$route.params.id); } } </script>RoomsCreate.vue:
<form @submit.prevent="addItems" class="form-horizontal" enctype="multipart/form-data"> <div class="form-group"> <label for="title" class="col-sm-2 control-label">Title<span class="red">*</span></label> <div class="col-sm-6"> <input type="text" name="title" class="form-control" id="title" v-model="itemsData.title"> <span class="text-danger">{{ errors.title?errors.title[0]:"" }}</span> </div> </div> <div class="form-group"> <label for="subtitle" class="col-sm-2 control-label">Subtitle<span class="red">*</span></label> <div class="col-sm-6"> <input type="text" name="subtitle" class="form-control" id="subtitle" v-model="itemsData.subtitle"> <span class="text-danger">{{ errors.subtitle?errors.subtitle[0]:"" }}</span> </div> </div>Script of Rooms.vue:
<script> import config from '../../../config'; export default { data(){ return{ items: [], itemsData:{ title : '', subtitle : '', } } }, methods: { deleteRoom: function (room) { var index = this.items.indexOf(room); this.items.splice(index, 1); } }, mounted() { axios.get(config.apiDomain+'/Rooms').then((response)=>this.items = response.data); } } </script>Script of RoomsCreate.vue:
<script> import config from '../../../config'; export default { data(){ return{ items: [], itemsData:{ title : '', subtitle : '', }, errors: { } } }, methods:{ addItems(){ axios.post(config.apiDomain+'/Rooms',this.itemsData).then(response=>{ this.this.itemsData = ""; this.$router.push('/admin/rooms'); }).catch(error=>{ this.errors = error.response.data; }); } } </script>The issue i am facing is when i click the edit in Room.vue, it redirects to the RoomsEdit.vue where i am not getting the values that was already created, i need to get those value when i go to RoomsEdit.vue there i should edit and update the content.
Alternative folder structure in Laravel
i'm creating a SPA application in Laravel that consists of an API (in PHP) and two applications in VueJS, an Admin Backoffice and a Frontend Web portal.
Ideally i'd like to keep the API in a separate domain like api.mydomain.com but devops told me that couldn't be cause it would mess up their CI structure namely because according to them it's hard to keep everything in sync that way...
So i'm forced to do everything in the same project, now, i don't think that my Vue Routes and stuff and stuff belong in the "resources" directory next to Laravel's translations and Blade views... And using blade views for the "catch-all" route means i cannot use Webpack's HTML plugin, also i think front-end and admin views should have different dependencies and webpack.config files.
So. I'm trying to do the following folder structure
/server |-api (replaces the APP folder) | |--v1/ |---Controllers/ |---Middleware/ |---Repositories |---Traits |---routes.php |--Core(Kernels) |--Models |--Jobs |--Providers | |-bootstrap |-config |-database |-resources(laravel blade views (if any) and translations) |-storage |-tests(phpunit) |-composer.json /admin |-components |-views |--partials/ |-utils |-services |-vuex |-App.vue |-config.js |-main.js |-routes.js |-index.html |-package.json |-webpack.config.jsThe idea is you always need to be routes through Laravel's index.php file and then in the laravel routes i have a catch-all which simply returns Vue's index.html i do this because i need a simple HTML root file in order to be able to take advantage of Webpack HTML plugin What do you guys think about this idea? Feasible? Any better ways of achieving this sort of separation?
define vue component in laravel
I'm using VueJS to load my data in view (using laravel), i do register my components in app.js file, and when i want to use them in one of my blade files it gives me this error :
(unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.)
my app.js file:
require('./bootstrap'); Vue.component('example', require('./components/Example.vue')); const app = new Vue({ el: 'body' }); Vue.component( 'passport-clients', require('./components/passport/Clients.vue') ); Vue.component( 'passport-authorized-clients', require('./components/passport/AuthorizedClients.vue') ); Vue.component( 'passport-personal-access-tokens', require('./components/passport/PersonalAccessTokens.vue') ); Vue.component('employer-enquiry-names', require('./components/Employer/Enquiry/Edit/Names.vue')); Vue.component('employer-enquiry-users', require('./components/Employer/Enquiry/Edit/Users.vue')); Vue.component('employer-enquiry-employer', require('./components/Employer/Enquiry/Edit/Employer.vue'));and here i used my component:
<div class="tab-content" id="enquiry_tabs"> <employer-enquiry-employer ref="employer_enquiry_employer"> </employer-enquiry-employer> <employer-enquiry-users ref="employer_enquiry_users"> </employer-enquiry-users> <div class="tab-pane fade" id="names"> <employer-enquiry-names ref="employer_enquiry_names" > </employer-enquiry-names> </div> </div> <script> var vm = new Vue({ el: '#enquiry_tabs' }); vm.$refs.employer_enquiry_employer.loadData(); $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { var activatedTab = e.target; // activated tab if (activatedTab.id == "names_link") { vm.$refs.employer_enquiry_names.loadData(); } else if (activatedTab.id == "users_link") { vm.$refs.employer_enquiry_users.loadData(); } else if (activatedTab.id == "employer_link") { vm.$refs.employer_enquiry_employer.loadData(); } }); </script>can anyone help me to resolve this? thanks
GAPI VS Standard HTTP Rest Call
What is the recommended way of connecting to the Google EndPoint API?
Use the Google provided gapi js library - gapi.client.load('helloworld', 'v1', callback, apiRoot);
Call the REST endpoints directly - https://project-id.appspot.com/_ah/api/myapi/v1/users
- Is there a better way?
I'm looking to integrate Google Endpoints with ReactJs or VueJs
source.vue doesn't work in my vue snippet in sublime text3?
I have a very annoying problem with my sublime snippet about .vue type flie.
Say I want to add a vue snippet in sublime on my own, and I want the vue tabtrigger below works in vue type file only.
I add these codes into my vue.sublime-snippet:
After saving this file in my sublime folder, I create a test.vue file and type vue and then press Tab.
But nothing happened. What I expected is Some text could appear after tabbing in test.vue file.
Why doesn't my snippet work on vue file?
PS: I changed source.vue into source.js source.php,etc in my snippet and tested in corresponding js, php file, they all work fine. Only vue didn't work out. Is there anything wrong with sublime identifying vue type file? How to solve this problem?
Recursive components in Vue js
I using vue components to display comments as well as replies to the comments. To display the replies I am simply using comment component recursively. however, I am getting an error.
Here's my code
<template> <div class="box"> <article class="media"> <figure class="media-left"> <p class="image is-64x64"> <img :src="comment.channel.data.imageUrl"> </p> </figure> <div class="media-content"> <div class="content"> <p> <strong><a :href="channelUrl">{{ comment.channel.data.name }}</a></strong> <small>{{ comment.created_at_human }}</small> <br> <p class="is-medium">{{ comment.body }}</p> <nav class="level is-mobile"> <div class="level-left"> <a class="level-item"> <span class="icon is-small"><i class="fa fa-comment-o"></i></span> </a> </div> </nav> </p> </div> </div> </article> <comment v-for="reply in comment.replies.data" :comment="reply" :key="reply.id"></comment> </div>I am getting the following error:
[Vue warn]: Error in render function: "TypeError: Cannot read property 'data' of undefined" found in ---> <Reply> at /home/vagrant/Laravel/youtube/resources/assets/js/components/Comment.vue... (1 recursive calls) <VideoComments> at /home/vagrant/Laravel/youtube/resources/assets/js/components/VideoComments.vue <VideoPlayerLayout> at /home/vagrant/Laravel/youtube/resources/assets/js/components/VideoPlayerLayout.vue <Root>Data is available in the object as I am using fractal to generate json output. Don't really know where am I going wrong.
Manage data array from methods to template syntax Vue
I used foreach to get data array based on id. Initially all went well. But something happen. I think I was wrong using forEach. But after I console.log. My array is fine. Like this :
const Thread = Vue.component('threadpage', function(resolve) { $.get('templates/thread.html').done(function(template) { resolve({ template: template, data : function() { return { data : { title : "Data Table Thread", count : {}, list : {} } }; }, methods : { GetData : function() { var data = {username : "example-username", data : { page : 0, length : 10, schedule : "desc" } }; var args = {"data" : JSON.stringify(data)}; var params = $.param(args); var url = "http://example-url"; var vm = this; DoXhr(url, params, function(response){ count = JSON.parse(response).data.count; vm.data.count = count; var result = []; result_data = JSON.parse(response).data.data; result_data.forEach(function(item) { //console.log(item); result[item._id] = { _id : item._id }; }); vm.data.list = result; console.log(result); }); } }, created : function(){ this.GetData(); } }); }); });As in vuejs.org, I used v-for like this :
<tbody v-for="item in data.list"> <tr> <td> {{ item._id }} </td> </tr> </tbody>The results don't display anything. Something wrong with my template syntax ? Where is my fault ? please help me. Thank you.
Importing a npm module into my javascript file
What is the proper way to import VueJs into my javascript file using NPM? I am getting a Vue is not defined error.
VueJs 2 hide and show DIVs in one html page, is this the right way?
I am building an application but not completely SPA, there are some div's in my page that I want to show and hide them step by step, here is my code :
<div v-if="sectionIs('section1')" class="container"> </div> <div v-if="sectionIs('section2')" class="container"> </div> <div v-if="sectionIs('section3')" class="container"> </div>And in my js file :
var vm = new Vue({ el: '#standard_registeration', data: { section : 'section1', }, computed: { sectionIs: function (sectionName) { return this.section === sectionName } } });I want to know if I'm doing this right, or is there a better approach?
what if I want to add animation later?
Where does `billlable` come from in Laravel Spark's `update-payment-method-stripe` Component?
If Laravel Spark, there's a vue component with the following inline template
<spark-update-payment-method-stripe :user="user" :team="team" :billable-type="billableType" inline-template> /* ... */ <div class="pull-right"> <span v-if="billable.card_last_four"> <i :class="['fa', 'fa-btn', cardIcon]"></i> ************@{{ billable.card_last_four }} </span> </div> /* ... */ </spark-update-payment-method-stripe>This template include the variable billable.card_last_four.
If I track down the definition file for the component, I see this
#File: resources/assets/js/spark-components/settings/payment-method/update-payment-method-stripe.js var base = require('settings/payment-method/update-payment-method-stripe'); Vue.component('spark-update-payment-method-stripe', { mixins: [base] });and if I track down the base component, I see a vue component defined
#File: spark/resources/assets/js/settings/payment-method/update-payment-method-stripe.jsmodule.exports = { props: ['user', 'team', 'billableType'], /* ... */
However, none of these components seem to define billable anywhere. I see a lot of references to this.billable.
#File: spark/resources/assets/js/settings/payment-method/update-payment-method-stripe.js /* ... */ this.form.address = this.billable.billing_address; this.form.address_line_2 = this.billable.billing_address_line_2; this.form.city = this.billable.billing_city; this.form.state = this.billable.billing_state; this.form.zip = this.billable.billing_zip; this.form.country = this.billable.billing_country || 'US'; /* ... */ placeholder() { if (this.billable.card_last_four) { return `************${this.billable.card_last_four}`; } return ''; } /* ... */Where does this billable property come from? I assume Vue's doing some form of meta-programming and/or magic to populate this, but I'm not familiar enough with Vue to know what's going on.
Aligning the contents of my footer properly
As I add more links to my footer the layout expands and the set of lists for each column becomes misaligned.
I want to ensure that each list set for each column is align horizontally in the same row. e.g. The title for each column is in the same row
levi | Using levi | legal
The below image has my column headers misaligned! :(. How would I align them properly so that when I add more to the list the alignment of the content in each column remains constant.
This is an exmaple of how I want my footer to look.
Here is my jsfiddle of how it is now
This is my HTML :
<md-layout id = "container" style = "max-height:40px;"> <md-layout md-column md-flex-xsmall="100" md-flex-small="100" md-flex-medium="33" md-flex-large="33" md-flex-xlarge="33"> <md-list> <md-list-item class = "md-display-2">levi</md-list-item> <router-link :to = "{ name: 'About' }"><md-row>About</md-row></router-link> <md-row >Customers</md-row > <md-row >Contact Us</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > <md-row >Support</md-row > </md-list> </md-layout> <md-layout md-column md-flex-xsmall="100" md-flex-small="100" md-flex-medium="33" md-flex-large="33" md-flex-xlarge="33"> <md-row class = "md-display-2" >Using levi</md-row > <md-row >Business</md-row > <md-row > <router-link class = "" :to = "{ name: 'Product' }"> Features </router-link> </md-row> <md-row >Pricing</md-row > <md-row >Pricing</md-row > </md-layout> <md-layout md-column md-gutter md-flex-xsmall="100" md-flex-small="100" md-flex-medium="33" md-flex-large="33" md-flex-xlarge="33"> <md-column class = "md-display-2">legal</md-column> <md-column></md-column> <md-column></md-column> </md-layout>Vue.js watcher not beeing executed when manually setting value
I have this Vue component:
methods: { ... toggleTyping: function () { this.composing = !this.composing; }, ... }, data: function () { return { composing: false, }; }, watch: { composing: function (val) { ... } }When I execute toggleTyping() the watcher is not beeing called. I'm very new on Vue.JS.
VueJs computed method error: Cannot read property 'words' of undefined" ?
This is My Js pseudo code :
var vm = new Vue({ el: '#test', data: { words: [{name:'1'}, {name:'2'}, {name:'3'},{name:'4'},{name:'5'},{name:'6'}], }, computed: { paginatedWords: function (words) { return vm.words.slice(2, 2); } } });I want to show only a portion of words with v-for, Here is the Html :
<ul> <li v-for="w in paginatedWords"> @{{w.name}} </li> </ul>But console gives me this error :
Error in render function: "TypeError: Cannot read property 'words' of undefined"What am I doing wrong?
Nuxt: load global data in background, unless hitting certain pages
I created a data-heavy website using Vue. Many of the site's pages don't use the data (about, etc), but a couple of them do (search). I start fetching the data in the background no matter what the initial page is, so when the user hits the search page the data is there and the page loads fast. That all works great.
I am now trying to server side render the site using Nuxt, and I can only get it so that every page waits for the data to render. If the user hits the search page, I want it to wait for the data before it renders, but if the user hits any other page, I would like it to render immediately and load the data in the background. Does anyone have any idea how to go about this?
Vue.JS Multiple checkbox series to filter apps
so here's my problem, I want to apply three filters to app thumbnails using Vue.js (I never used that framework before). It works fine for the first filter but I don't know how to proceed for the other ones. The goal is to be able to pick only one checkbox from each category (Platform, Field of activity and Device).
Screenshot of what it should look like. ("Toutes" meaning "All")
Here's the HTML
<div id="filter-realisations"> <div id="filter"> <div class="filter_container"> <h3>Filtrer</h3> <div class="filter"> <p>Plateforme</p> <input type="radio" v-model="selectedPlatform" value="AllPlatform" id="AllPlatform"><label for="AllPlatform">Toutes</label> <input type="radio" v-model="selectedPlatform" value="iOS" id="iOS" /><label for="iOS">iOS</label> <input type="radio" v-model="selectedPlatform" value="Android" id="Android" /><label for="Android">Android</label> </div> <div class="filter"> <p>Secteur</p> <input type="radio" v-model="selectedSecteur" value="AllSecteur" id="AllSecteur" /><label for="AllSecteur">Toutes</label> <input type="radio" v-model="selectedSecteur" value="grandPublic" id="grandPublic"/><label for="grandPublic">Grand public</label> <input type="radio" v-model="selectedSecteur" value="metier" id="metier" /><label for="metier">Métier</label> <input type="radio" v-model="selectedSecteur" value="marchesPublics" id="marchesPublics" /><label for="marchesPublics">Marchés Publics</label> </div> <div class="filter"> <p>Device</p> <input type="radio" v-model="selectedDevice" value="AllDevice" id="AllDevice" /><label for="AllDevice">Toutes</label> <input type="radio" v-model="selectedDevice" value="Smartphone" id="Smartphone" /><label for="Smartphone">Smartphone</label> <input type="radio" v-model="selectedDevice" value="Tablet" id="Tablet" /><label for="Tablet"> Tablette</label> <input type="radio" v-model="selectedDevice" value="Watch" id="Watch" /><label for="Watch"> Montre connectée</label> </div> </div> </div> <div id="realisations"> <div class="realisations_container"> <div class="realisations_bloc" v-for="app in filteredRealisations" v-bind:key="app"> <img v-bind:src='"img/realisations/"+app.name+".jpg"' alt="app.name"> <div class="overlay"> <div class="app_description"><p>{{app.name}}</p></div> <div class="platform_container"> <div class="device"> <img v-bind:src='"img/"+app.device+".svg"' alt="app.device"/> </div> <div class="os"> <img v-bind:src='"img/"+app.platform+".svg"'alt="app.platform"/> </div></div> </div> </div> </div> </div> </div>And here's the script
var vm = new Vue({ el: "#filter-realisations", data: { realisations: [ { name: "ASM", platform: "iOS", secteur: "grandPublic", secteur: "grandPublic", device:"Watch" }, { name: "Biodiversea", platform: "Android", secteur: "marchesPublics", device:"Tablet" }, { name: "CDBB", platform: "iOS", secteur: "grandPublic", device:"Smartphone" }, { name: "Centre France", platform: "iOS", secteur: "grandPublic", device:"Watch" }, { name: "Clermont", platform: "Android", secteur: "grandPublic", device:"Tablet" }, { name: "Dassault", platform: "iOS", secteur: "metier", device:"Smartphone"}, { name: "Journal", platform: "iOS", secteur: "metier", device:"Smartphone" }, { name: "Somfy", platform: "Android", secteur: "metier", device:"Smartphone" }, { name: "Sortir.vosges", platform: "Android", secteur: "metier", device:"Smartphone" }, { name: "Sud Radio", platform: "Android", secteur: "metier", device:"Smartphone" }, { name: "Verifrom", platform: "Android", secteur: "metier", device:"Smartphone" }, { name: "Sports", platform: "iOS", secteur: "marchesPublics", device:"Watch" } ], selectedSecteur : "AllSecteur", selectedPlatform: "AllPlatform", selectedDevice : "AllDevice" }, computed: { filteredRealisations: function() { var vm = this; var platform = vm.selectedPlatform; var secteur = vm.selectedSecteur; var device = vm.selectedDevice; if(platform === "AllPlatform") { return vm.realisations; } else { return vm.realisations.filter(function(app) { return app.platform === platform; }); } if(secteur === "AllSecteur") { return vm.realisations; } else { return vm.realisations.filter(function(app) { return app.secteur === secteur; }); } if(device === "AllDevice") { return vm.realisations; } else { return vm.realisations.filter(function(app) { return app.device === device; }); } } } });How Could You Use a Speech Interface?
Last month in San Francisco, my colleagues at Mozilla took to the streets to collect samples of spoken English from passers-by. It was the kickoff of our Common Voice Project, an effort to build an open database of audio files that developers can use to train new speech-to-text (STT) applications.
What’s the big deal about speech recognition?
Speech is fast becoming a preferred way to interact with personal electronics like phones, computers, tablets and televisions. Anyone who’s ever had to type in a movie title using their TV’s remote control can attest to the convenience of a speech interface. According to one study, it’s three times faster to talk to your phone or computer than to type a search query into a screen interface.
Plus, the number of speech-enabled devices is increasing daily, as Google Home, Amazon Echo and Apple HomePod gain traction in the market. Speech is also finding its way into multi-modal interfaces, in-car assistants, smart watches, lightbulbs, bicycles and thermostats. So speech interfaces are handy — and fast becoming ubiquitous.
The good news is that a lot of technical advancements have happened in recent years, so it’s simpler than ever to create production-quality STT and text-to-speech (TTS) engines. Powerful tools like artificial intelligence and machine learning, combined with today’s more advanced speech algorithms, have changed our traditional approach to development. Programmers no longer need to build phoneme dictionaries or hand-design processing pipelines or custom components. Instead, speech engines can use deep learning techniques to handle varied speech patterns, accents and background noise – and deliver better-than-ever accuracy.
The Innovation PenaltyThere are barriers to open innovation, however. Today’s speech recognition technologies are largely tied up in a few companies that have invested heavily in them. Developers who want to implement STT on the web are working against a fractured set of APIs and support. Google Chrome supports an STT API that is different from the one Apple supports in Safari, which is different from Microsoft’s.
So if you want to create a speech interface for a web application that works across all browsers, you would need to write code that would work with each of the various browser APIs. Writing and then rewriting code to work with every browser isn’t feasible for many projects, especially if the code base is large or complex.
There is a second option: You can purchase access to a non-browser-based API from Google, IBM or Nuance. Fees for this can cost roughly one cent per invocation. If you go this route, then you get one stable API to write to. But at one cent per utterance, those fees can add up quickly, especially if your app is wildly popular and millions of people want to use it. This option has a success penalty built into it, so it’s not a solid foundation for any business that wants to grow and scale.
Opening Up Speech on the WebWe think now is a good time to try to open up the still-young field of speech technology, so more people can get involved, innovate, and compete with the larger players. To help with that, the Machine Learning team in Mozilla Research is working on an open source STT engine. That engine will give Mozilla the ability to support STT in our Firefox browser, and we plan to make it freely available to the speech developer community, with no access or usage fees.
Secondly, we want to rally other browser companies to support the Web Speech API, a W3C community group specification that can allow developers to write speech-driven interfaces that utilize any STT service they choose, rather than having to select a proprietary or commercial service. That could open up a competitive market for smart home hubs–devices like the Amazon Echo that could be configured to communicate with one another, and other systems, for truly integrated speech-responsive home environments.
Where Could Speech Take Us?Voice-activated computing could do a lot of good. Home hubs could be used to provide safety and health monitoring for ill or elderly folks who want to stay in their homes. Adding Siri-like functionality to cars could make our roads safer, giving drivers hands-free access to a wide variety of services, like direction requests and chat, so eyes stay on the road ahead. Speech interfaces for the web could enhance browsing experiences for people with visual and physical limitations, giving them the option to talk to applications instead of having to type, read or move a mouse.
It’s fun to think about where this work might lead. For instance, how might we use silent speech interfaces to keep conversations private? If your phone could read your lips, you could share personal information without the person sitting next to you at a café or on the bus overhearing. Now that’s a perk for speakers and listeners alike.
Want to participate? We’re looking for more folks to participate in both open source projects: STT engine development and the Common Voice application repository.
If programming is not your bag, you can always donate a few sentences to the Common Voice Project. You might read: “It made his heart rise into his throat” or “I have the diet of a kid who won $20.” Either way, it’s quick and fun. And it helps us offer developers an open source option that’s robust and affordable.
The post How Could You Use a Speech Interface? appeared first on The Mozilla Blog.
VueJS Filter Array Based on Input
I have a vueJS application and I'm trying to filter an array based on an input from a form.
The problem is my array autocomplete isn't getting populated with the visitors that match the query of the first name?
My HTML
<input class="input" placeholder="First Name" v-model="visitor.first" @keyup.enter="searchVisitors">My Vue Instance
<script> new Vue({ el: '#app', data: { previousVisitors: [], autocomplete: [], visitor: {} }, mounted() { axios.get('/visitors/all').then(response => this.previousVisitors = response.data); }, methods: { searchVisitors() { var q = this.visitor.first; this.autocomplete = this.previousVisitors.filter(item => {return item.firstName === q}); console.log(this.autocomplete); } } }); </script>I can confirm the repsonse from the Axios which is currently populating the previousVisitors array contains the FirstName of each previous visitor.
I have used the method wrongly here?