Invalid string length at repeat$1 (VueJS) [Resolved: continue is a reserved JavaScript word] - vue.js

I'm having the Error in execution of function repeat$1 while compiling a very simple VueJS template. This error prevents the app from compiling.
Can't wrap my head against what's wrong whit the template.
Here's the code:
(I replaced parts of the template that consisted solely on text with the word "text".)
<template>
<div class="container">
<div class="row">
<div class="col-lg-10 mx-auto" v-if="showPrivacyDisclaimer">
<div class="card mt-4">
<div class="card-body">
<div class="card-title">
text
</div>
<p>
<b>text</b>
</p>
<p>
text.
</p>
<p>
text
</p>
<div class="text-sm">
<a #click="details = true" style="text-decoration: underline">
Leer más: ¿Qué datos recopilamos?
</a>
<p v-if="details">
text
</p>
<br>
<a #click="rights = true" style="text-decoration: underline">
Leer más: ¿Cómo ejercer tus derechos sobre estos datos?
</a>
<p v-if="rights">
text
</p>
</div>
</div>
<div class="card-footer">
<button type="button"
class="btn btn-primary"
#click="continue()">
Aceptar y continuar
</button>
</div>
</div>
<img :src="baseUrl + '/public/img/eks-logo.svg'"
class="mt-4" style="max-width: 10rem">
<p class="text-muted mt-4 text-sm">
text
<br>
more text
</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'Home',
data() {
return {
baseUrl: process.env.VUE_APP_PHP_BASE_URL,
showPrivacyDisclaimer: false,
details: false,
rights: false,
}
},
mounted()
{
let hasPrivacyAccepted = window.localStorage.getItem('pda');
if (!hasPrivacyAccepted) {
this.showPrivacyDisclaimer = true;
} else {
this.continue();
}
},
methods: {
continue()
{
window.localStorage.setItem('pda', 1);
this.$router.replace({
path: '/encuesta/' + this.$route.query.e,
query: this.$route.query
})
}
}
}
</script>
If I completely remove everything between the <template> tags (except the first div that is required), the app starts compiling again.
I have tried progressively deleting parts of the template that use Vue directives (v-if, etc.). But this didn't made the app compile :(
Please help!
Update: I forgot to mention I've already tried deleting and re-installing node_modules
Update 2: I found the source of the bug. continue is a reserved JS word.

You can't use #click="continue()"
This is a reserved word for javascript.
You can see the full list here :
https://www.w3schools.com/js/js_reserved.asp

Update: I started refactoring the template in two views and a more descriptive error message pop'd-up.
The error was that I was using a JavaScript reserved word as a method name (continue is a reserved word).

Related

Vue's reactivity not triggered when using Bootstrap 5's alert div

Vue's reactivity not triggered when using Bootstrap 5's alert div.
See my code:
<template>
<div>
<div
v-if="alertICDMsg!==''"
id="alertICDCode"
class="alert alert-info alert-dismissible fade show"
role="alert"
>
<i class="fa-solid fa-lightbulb" />
<strong> Note!</strong> <span v-html="alertICDMsg" />
<button
type="button"
class="btn-close"
data-bs-dismiss="alert"
aria-label="Close"
/>
</div>
<div class="input-group mb-3">
<div class="col-xs-1">
<input
id="ICDCode"
v-model="editing_icdCode"
class="form-control"
placeholder="ICD Code"
aria-label="ICD Code"
#input="ICDCodeSearchRequested"
>
</div>
<input
id="Diagnosis"
v-model="editing_diagnosis"
type="text"
class="form-control"
placeholder="Diagnosis"
aria-label="Diagnosis"
aria-describedby="basic-addon1"
list="icdsearchlist"
#change="SelectedDiagnosisTextOption"
#input="ICDTextSearchRequested"
>
<datalist id="icdsearchlist">
<option
v-for="(disease_option, index) in icd_diagnosis_options"
:key="index"
>
{{ disease_option }}
</option>
</datalist>
<button
id="btnAddDiagnoses"
href="#"
class="btn btn-primary mx-1"
#click="AddDiagnosis"
>
<i class="fal fa-plus-circle" />
</button>
<button
id="btnCopyPreviousDiagnoses"
href="#"
class="btn btn-primary BtnSaveGroup mx-1"
>
<i class="far fa-history" />
</button>
<button
id="quickbill"
class="btn btn-primary mx-1"
>
<i class="fas fa-search-plus" />
</button>
<button
id="clearICD"
class="btn btn-danger mx-1"
#click="ClearICDFields"
>
<i class="fad fa-times-circle" />
</button>
</div>
</div>
<template>
<script>
export default {
data() {
return {
alertICDMsg:"",
};
},
watch: {
alertICDMsg: {
handler(val) {
console.log(`Val for alertICDMsg changed to :${val}`);
},
immediate: true,
deep: true,
},
},
methods: {
ICDCodeSearchRequested() {
console.log(`Search by ICD code`);
this.alertICDMsg="Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box."
console.log(`alertICDMsg is ${this.alertICDMsg}`);
setTimeout(function() {
console.log(`Dismissing alert`);
this.alertICDMsg='';
console.log(`alertICDMsg is ${this.alertICDMsg}`);
}, 5000);
},
},
}
</script>
Console log:
Search by ICD code
SubClinicalBlock.vue?d801:291 alertICDMsg is Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:220 Val for alertICDMsg changed to :Searching in ICD Code box will search only by code. To search by a diagnosis name, type in the Diagnosis box.
SubClinicalBlock.vue?d801:293 Dismissing alert
SubClinicalBlock.vue?d801:298 alertICDMsg is
The problem is that after 5 seconds, though the value of the variable changes, the alert is still visible.
I checked some similiar questions, and have seen this happening when bootstrap's javascript wasnt loaded. But for me, Bootstrap v5.0.1 JS is being loaded from the CDN and appears in the sources tab in Chrome.
Try to change the function inside of setTimeout to arrow function like this
setTimeout(() => { // code here })
The this inside of setTimeout(function () => {}) reference to the wrong context (the function itself) instead of the Vue component.
The arrow function doesn't have the this binding so when you use the arrow function the this keyword will reference the Vue component and change the state.
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

How can I make my section hide only after the submit button is pressed. right now the section disappears after I press one letter

vue.js, how can I make my section hide only after the submit button is pressed. right now the section disappears after I press one letter. I want the V-if and V-else to activate only after the user has submitted their request. or if routing the results on to a different page would easier id like to go that route also.
<template>
<div class="home">
<section id="whiteClawVideo" class="videoWrapper d-block w-100">
<div class="video-container fluid">
<iframe width="100%" height="600" src="https://www.youtube.com/embed/JORN2hkXLyM?
autoplay=1&loop=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope;
picture-in-picture" allowfullscreen></iframe>
</div>
</section>
<form #submit.prevent="SearchMovies()" class="search-box">
<input type="text" placeholder="What are you looking for? " v-model="search" />
<input type="submit" value="Search">
</form>
<div class="movies-list" v-if="search !== ''" >
<div class="container">
<div class="row">
<div class="col-3" v-for="movie in movies" :key="movie.imdbID">
<router-link :to="'/movie/'+movie.imdbID" class="movie-link">
<img class="movieImg" height="100%" :src="movie.Poster" alt="Movie Poster" />
<div class="type">{{ movie.Type }}</div>
<div class="detail">
<p class="year">{{movie.Year}}</p>
<h3>{{ movie.Title }}</h3>
<p>{{movie.imdbID}}</p>
</div>
</router-link>
</div>
</div>
</div>
</div>
<div class="container" v-else>
<MovieSection />
<SecondMovieSection />
</div>
</div>
</template>
import { ref } from 'vue';
import env from '#/env.js';
import MovieSection from '#/components/MovieSection.vue';
import SecondMovieSection from '#/components/SecondMovieSection.vue'
export default {
components: {
MovieSection,
SecondMovieSection
},
setup () {
const search = ref("");
const movies = ref([]);
const SearchMovies = () => {
if (search.value !== "") {
fetch(`API_HERE`)
.then(response => response.json())
.then(data => {
console.log(data)
movies.value = data.Search;
})
}
}
return {
search,
movies,
SearchMovies
}
}
}
Well, it closes once you type a single character because search is a model - it updates on every keypress you do within input it's bound to. What you wanna do instead is hide form based on whether you have entries in your movies array or not, so try changing v-if="search !== ''" to v-if="!movies.length"

How to display a string value in template section in vue.js?

I developed one page which is responsible for showing order success message and i am getting response from backend which contains orderId ,i am getting that response and i am able to bind in front end but i am getting my output as a json format in my UI page ,but what i need is to display only orderID value only (like a string).please help me to fix this issue...
i want to display orderID value only
OrderPlace.vue
<template>
<div class="order-place">
<div class="image-container">
<img src="../assets/success.png" alt="not found" />
</div>
<div class="title-container">
<p>Order placed Successfully</p>
</div>
<div class="message-section">
<p>Hurray!!!your order is confirmed and placed successfully contact us in below details
for further communication..</p>
</div>
<div class="order-id">
{{orderNumber}}
</div>
<div class="title-section">
<div class="email-us">
<p>Email-us</p>
</div>
<div class="contact-us">
<p>Contact-us</p>
</div>
<div class="address">
<p>Address</p>
</div>
</div>
<div class="email-sec">
<p>admin#bookstore.com</p>
</div>
<div class="contact-sec">
<p>+918163475881</p>
</div>
<div class="address-sec">
42, 14th Main, 15th Cross, Sector 4 ,opp to BDA complex, near Kumarakom restaurant, HSR Layout, Bangalore 560034
</div>
<div class="button">
<router-link to="/dashboard" class="btn">Continue Shopping</router-link>
</div>
</div>
</template>
<script>
import service from '../service/User';
// import { EventBus } from "./event-bus.js";
export default {
name: 'OrderPlace',
data(){
return{
successTitle:'Order placed Successfully',
adminEmailSection:'Email-us',
adminContactSection:'Contact-us',
adminAddressSection:'Address',
adminEmail:'admin#bookstore.com',
adminMobNum:'+918163475881',
orderNumber: ''
}
},
created() {
service.confirmMail().then(response =>
(this.orderNumber=JSON.stringify(response.data))
)
}
}
</script>
You're stringifying an Object of { message: string; orderId: number } which of course will result in that "string" of an Object being displayed when you use
<div class="order-id">
{{orderNumber}}
</div>
Like Boussadjra said just assign the id to the corresponding data field
service.confirmMail().then(response =>
(this.orderNumber=response.data.orderId)
)
Just assign the orderID to the orderNumber:
service.confirmMail().then(response =>
(this.orderNumber=response.data.orderID)
)

VUE's focus() method return a console error? How to use it correctly?

I'm trying to focus on several elements of my form but the first one, despite being applied, returns an error by console.
This is my template:
<div class="container">
<div class="col-xs-12">
<div class="row">
<h1 class="animal-title">Your selection is : </h1>
</div>
<div class="wrapper">
<form class="first-form" #submit.prevent="onSubmit">
<div class="image-wrapper">
<div class="sel-image">
<div v-on:click="imageSelected = true" v-for="item in items" v-bind:key="item.id">
<label>
<input
type="radio"
name="selectedItem"
ref="item"
:value="item.id"
v-model="itemFormInfo.selectedItem"
#change="onChangeItem($event)"
/>
<img v-if="item.id === 1" src="../../assets/1.png" />
<img v-if="item.id === 2" src="../../assets/2.png" />
<img v-if="item.id === 3" src="../../assets/3.png" />
</label>
<p class="cie-animal-subtitle">{{item.name}}</p>
</div>
</div>
</div>
<div class="form-select">
<div v-show="filteredStock && (imageSelected || itemFormInfo.selectedItem) > 0">
<h1 v-if="this.itemName === 'Phone' || this.itemName === 'Tablet'" for="selectedItem" ref="itemVisible">
Select the brand of your <span>{{this.itemName}}</span> :
</h1>
<h1 v-if="this.itemName === 'PC'" for="selectedBreed" ref="itemVisible">
Select the type of your <span>{{this.itemName}}</span> :
</h1>
<select
ref="brand"
class="form-control"
id="selectedBrand"
v-model="itemFormInfo.selectedBrand"
#change="onChangeBrand($event)">
<option v-for="brand in filteredBrand" v-bind:key="brand.name">{{ brand.name }}</option>
</select>
<div v-show="this.isBrandSelected">
<h1>What are you going to use your
<span>{{itemName}}</span> for ?
</h1>
<input
type="text"
id="componentName"
ref="componentName"
class="form-control fields"
style="text-transform: capitalize"
v-model="itemFormInfo.component"
#keypress="formChange($event)"
/>
<div class="loader-spinner" v-if="loading">
<app-loader/>
</div>
</div>
</div>
</div>
<div class="service-options" v-show="isComponentCompleted">
<div class="from-group">
<h1>
Here are the options for your <span>{{this.itemFormInfo.component}}</span> :
</h1>
<div class="services">
<div class="column-service" v-for="option in options" v-bind:key="option.name">
<div class="service-name">{{option.name}}</div>
<div class="service-price">{{option.price.toString().replace(".", ",")}} </div>
</div>
</div>
and here my first method
onChangeItem(event) {
let item = event.target._value;
this.itemName = this.getItemName(item);
if (this.isItemSelected = true) {
this.isItemSelected = false;
this.isComponentCompleted = false;
this.isLoaderFinished = false;
this.itemFormInfo.name = ""
}
this.$refs.item.focus();
},
in this function that I control my first input, the focus is working but it returns me by console the following error:
"this.$refs.item.focus is not a function at VueComponent.onChangeItem"
I have seen some references to similar cases where they involved the reference in a setTimeout or used the this.$nextTick(() => method but it didn't work in my case.
What am I doing wrong?
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
Thank you all for your time and help in advance
How can I focus on the next select with ref brand, once I have chosen the value of the first input?
You want to put focus on brand but your onChangeItem handler is calling this.$refs.item.focus() (trying to focus item). Seems strange to me...
Reason for the error is you are using ref inside v-for.
Docs: When used on elements/components with v-for, the registered reference will be an Array containing DOM nodes or component instances
So the correct way for accessing item ref will be this.$refs.item[index].focus().
Just be aware that right now v-for refs do not guarantee the same order as your source Array - you can find some workarounds in the issue discussion...

Cannot read property 'focus' of undefined in VUE When setting focus to button

I am new to vue I have component which if the endpoint fails, calls my generic 'Error' modal. All this is working fine but I keep getting the following error:
Cannot read property 'focus' of undefined
This only happens for the else part of my method function.
For this specific issue is I my 'failedPrcess' equals any of the following, this is when I get is, all others are fine:
existOrderSearchProdOrders
stockSearchStockLevels
cartFetchCouriers
Code
<template>
<div class="modal fade danger-modal" id="errorModal" tabindex="-1" role="dialog" aria-labelledby="errorModalTitle" aria-hidden="true"
data-keyboard="false" data-backdrop="static" style="z-index: 99999">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content danger-modal-content">
<div class="modal-header danger-modal-headerfooter">An error has occurred</div>
<div class="modal-body">
<p v-if="failedProcess === 'appGetAccount' || failedProcess === 'existOrderSearchProdOrders' || failedProcess === 'stockSearchStockLevels'
|| failedProcess === 'cartFetchCouriers'">
{{ contactTxt | capitalize }}
</p>
<p v-else-if="errorCount < 3">If the error continues, {{ contactTxt }}</p>
<p v-else>As the error has continued, {{ contactTxt }}</p>
<p>
<b>
01234 567890
<br />
Open from 00:00 to 07:00
</b>
</p>
<p>Advising of what you were doing when the error occurred.</p>
</div>
<div class="modal-footer danger-modal-headerfooter">
<a v-if="failedProcess === 'appGetAccount'" ref="logoutButton" class="btn btn-primary" :class="logoutButtClicked" #click="logoutClicked = true" href="/site/logout">
<span v-if="!logoutClicked" id="logoutButtonLabel">Logout</span>
<span v-else id="logoutSpinner">
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Logging out
</span>
</a>
<router-link v-else-if="failedProcess === 'fetchOrderReportDetails'" to="/review" tag="button"
ref="existOrdersButton" class="btn btn-primary" type="button" data-dismiss="modal" #click.native="closeButton">
Return to existing orders
</router-link>
<button v-else-if="errorCount < 3 && (failedProcess !== 'productsFetchProducts' && failedProcess !== 'existOrderSearchProdOrders'
&& failedProcess !== 'stockSearchStockLevels' && failedProcess !== 'cartFetchCouriers')" ref="closeButton" class="btn btn-primary"
type="button" data-dismiss="modal" #click="closeButton">
Close
</button>
<router-link v-else to="/" tag="button" ref="homeButton" class="btn btn-primary" type="button" data-dismiss="modal" #click="closeButton">
Return to homepage
</router-link>
</div>
</div>
</div>
</div>
</template>
<script>
import * as params from '../params';
export default {
name: "ErrorModal",
data() {
return {
contactTxt: 'please contact us on:',
errorCount: 0,
failedProcess: '',
}
},
mounted() {
VueEvent.$on('show-error-modal', (failedProcess) => {
if (this.failedProcess !== failedProcess) {
this.errorCount = 0;
}
this.failedProcess = failedProcess;
$('#errorModal').modal('show').on('shown.bs.modal', this.focus);
});
},
methods: {
focus() {
if (this.failedProcess === 'appGetAccount') {
this.$refs.logoutButton.focus();
} else if (this.failedProcess === 'fetchOrderReportDetails') {
this.$refs.existOrdersButton.$el.focus();
} else if (this.errorCount < 3 && this.failedProcess !== 'productsFetchProducts') {
this.$refs.closeButton.focus();
} else {
this.$refs.homeButton.$el.focus();
}
},
}
}
</script>`enter code here`
I've tried using v-if before and I also had similar problems and the best solution I found was, instead of using v-if/v-else-if/v-else, use v-show instead to perform conditional rendering.
Also, as the Vue.js doc says:
Generally speaking, v-if has higher toggle costs while v-show has higher initial render costs. So prefer v-show if you need to toggle something very often, and prefer v-if if the condition is unlikely to change at runtime.