Vue.js on click method , not working on laravel project - javascript

As the code below , the vue.js component works correctly , but the on-click method does not work at all and there is no cached errors . it seems that the function does not get called . When webpack is disabled , the code works correctly.
The HTML code :
<div class="row my-4">
<div class="col-8">
<h5>{{price}} $$</h5>
</div>
<div class="col-4">
<button type="button" v-on:click="inquiry" class="btn btn-yui mx-auto btn-block">price</button>
</div>
</div>
Vue.js section
methods: {
inquiry: function(){
axios.post(`http://localhost:8000/api/brand/panel/get/price/plan`,this.form,{
headers: {'Accept': 'application/json'}
})
.then(response => {
this.price = response.data;
})
.catch(function (error) {
console.log(error);
});
},

You use
<script src="{{ asset('js/app.js') }}" defer></script>
or no need to mix or something under app.blade.php files.This line default call layouts/app.blade.php
it's work for me.
Thank you.

Related

Prevent TypeError: updates[0] is undefined in Vue.js/Django application

I'm developing a Django/Vue.js application.
Right after the login form, the Django view redirects to the user/username page, in which the Vue.Js file loads the data from the server. Here is the code:
async created(){
await this.getUpdates();
}
The detail of the getUpdates() function is reported below; basically, it posts at Django the date that the server needs to do its calculations.
async getUpdates(){
await fetch(baseurl + 'getupdates',
{
method: 'post',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRFToken': await this.getCsrfToken()
},
body: JSON.stringify(this.date)
}
);
var response = await this.loadUpdates();
this.updates = await response.json()
},
async loadUpdates(){
await this.getUser();
var response = await fetch(baseurl + 'loadupdates',
{
method: 'post',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRFToken': await this.getCsrfToken()
},
body: JSON.stringify(this.date)
}
);
this.updates = await response.json()
}
The html snippet that uses these updates are reported below
<!--Avvisi-->
<h3>Avvisi:</h3>
<div class="container" >
<div class="row" v-if="updates[0].length">
<div v-for="notice, index in updates[0]" class="col-md-3 col-6 my-1">
<!--Qua metto le carte-->
<div class="card">
<div class="card-body">
<h4 class="card-title">[[notice.titolo]]</h4>
<p><a v-bind:href="'notices/'+ notice.id" tabindex=0>Vedi dettaglio</a></p>
<button class="btn btn-primary" #click="hide(notice)" tabindex=0>Nascondi</button>
</div>
</div>
</div>
</div>
<div class="row" v-else>
Nessun nuovo avviso oggi
</div>
</div>
<br>
The problem is that when I firstly log in to the page the console log shows:
TypeError: updates[0] is undefined
I think to know the reason why this happens: when I log in the Vue instance calls the this.getUpdates() function but, since it's an asynchronous call, it renders the HTML whiteout waiting for the response, and therefore the updates[0] , in the first evaluation, is empty.
Is there a solution for this issue? Thank you.
Your guess is correct. There is no way to 'pause' the execution inside the lifecycle hooks. The best practice is to load your components with a loading state and then trigger a flag (or use a watcher property) to update the components once the data is loaded.
A simple way to solve this issue would be to wrap it inside a conditional div that checks if updates is defined yet:
<div v-if="updates && updates.length>0">
<div class="row" v-if="updates[0].length">
<div v-for="notice, index in updates[0]" class="col-md-3 col-6 my-1">
<!--Qua metto le carte-->
<div class="card">
<div class="card-body">
<h4 class="card-title">[[notice.titolo]]</h4>
<p><a v-bind:href="'notices/'+ notice.id" tabindex=0>Vedi dettaglio</a></p>
<button class="btn btn-primary" #click="hide(notice)" tabindex=0>Nascondi</button>
</div>
</div>
</div>
</div>
<div class="row" v-else>
Nessun nuovo avviso oggi
</div>
</div>
Eventually though, you should implement a loading state to let user know that some data is being fetched in the background.
I don't have much experience with Django routing, and how it couples with Vue, but in Vue-router, and generally speaking, if your component depends completely upon the data being fetched, you do it before the navigation is accepted, and then pass it onto the components. For anyone else using Vue-router, here's a link on how to do that.

Need assistance with Handlebarsjs, template not working/rendering

Before testing Handlebarsjs for myself, I searched for some tutorial on YouTube and watched it. So basically I followed the example that was shown on the video, although for some reason mine's not working.
Below is the template script that is in my html file (also the container for the template).
<div id="recents">
<div id="recents-template-container" class="grid-container">
</div>
</div>
<script id="recents-template" type="text/x-handlebars-template">
{{#each jobposts}}
<div id="box-{{#key}}" class="recents-box flex-container">
<div class="box-row">
<span id="jobtitle">{{jobtitle}}</span>
</div>
<div class="box-row">
<span id="company">{{company}}</span>
</div>
<div class="box-row">
<span id="year">{{experience.year}}</span>
<span id="months">{{experience.months}}</span>
</div>
<div class="box-row">
<span id="location">{{location}}</span>
</div>
</div>
{{/each}}
</script>
<script type="module" src="src/js/index.js"></script>
Note: these two are at the end of the body tag.
And below is my index.js file
//index.js
import {recents} from "./query.js";
recents();
and query.js
//query.js
export function recents(){
const date = new Date();
const isoDate = `${date.getFullYear()}-0${(date.getMonth()+1)}-${date.getDate()}`;
const url = `http://localhost:3000/jobposts?dateposted_like=${isoDate}&_limit=5`;
$(document).ready(function() {
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function(data){
console.log(data);
createRecents(data);
},
error: function(data){
console.error(data);
}
});
function createRecents(data){
const template = $("#recents-template").html();
const compiledTemplate = Handlebars.compile(template);
const html = compiledTemplate(data);
$("#recents-template-container").html(html);
}
});
}
I also tried the template on the website of Handlebarjs, and it wworks. Is there something wrong in how I implemented it or how I coded it?
P.S. Sorry if my code looks bad.

push is not a function vuejs

I'm making an app with VueJS and Laravel. I'm getting an error, the push is not a function when I clicked an add to cart button. Everything is working here fine but methods addToCart gives error push is not a function. when I first click add to cart button it gives that error and once I refresh the page I can see a product in cart and again if click adds to cart button this time error is not seen, works perfectly. when cart[] is empty it gives error push is not a function, but when cart[] has at least one element I don't get that error.
Any help would be greatly appreciated.
productlist.vue
<template>
<div class="col-md-7">
<div class="card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">{{ product.name }}</h5>
<p class="card-text">{{ product.price }}
</p>
<button class="btn btn-primary" #click="addProductToCart(product)">Add to cart</button>
</div>
</div>
</div>
</template>
<script type="text/javascript">
export default{
props:['product'],
data(){
return{
}
},
methods:{
addProductToCart(product){
axios.post('/products/create',{
product : product
}).then((response)=>{
console.log(response)
this.$emit('addedToCart',product)
});
}
}
}
</script>
cart.vue
<template>
<div class="col-md-4">
<li v-for="(item,index) in cart">
{{ item.name }}-{{ item.price }}
<button #click="removeitem(index)">Remove</button>
</li>
</div>
</template>
<script type="text/javascript">
export default{
props:['cart'],
}
</script>
Main.vue
<template>
<div>
<div class="col-md-7" v-for="product in products">
<Productlist :product="product" #addedToCart="addedToCart"></Productlist>
</div>
<Cart :cart="cart" ></Cart>
</div>
</template>
<script type="text/javascript">
import Productlist from './Productlist';
import Cart from './Cart';
export default{
data(){
return{
products:[],
cart: [ ]
}
},
mounted() {
//get all products and show in page
axios.get('/products')
.then((response)=>{
this.products = response.data;
});
// get only those products that are added to cart
axios.get('/list')
.then((response)=>{
this.cart= response.data;
console.log(response)
});
},
methods:{
addedToCart(product){
this.cart.push(product)
}
},
components:{Productlist,Cart}
}
</script>
i don't sure if this will resolve your problem but is unnecessary do:
<button class="btn btn-primary" #click="addProductToCart(product)">Add to cart</button>
because you have product as prop of the component, should be #click="addProductToCart" without problem.
and your method should be so:
addProductToCart() {
axios
.post('/products/create', {
product: this.product,
})
.then(response => {
console.log(response);
this.$emit('addedToCart', this.product);
});
}
One thing more, use kebab-case to call the key string when you emit to the parent component:
this.$emit('addedToCart', this.product);
replace it with:
this.$emit('added-to-cart', this.product);
Then in your parent component you have:
<Productlist :product="product" #addedToCart="addedToCart"></Productlist>
replace it with:
<Productlist :product="product" #added-to-cart="addedToCart"></Productlist>
I guess this last things will resolve your problem according the Vue documentation.

Vuejs component couldn't access data

I have a simple component but I couldn't access data inside component
This is my component
<template>
<!-- success -->
<div class="message-box message-box-success animated fadeIn" id="message-box-success">
<div class="mb-container">
<div class="mb-middle">
<div class="mb-title"><span class="fa fa-check"></span> {{title}} </div>
<div class="mb-content">
<p>{{successMessage}}</p>
</div>
<div class="mb-footer">
<button class="btn btn-default btn-lg pull-right mb-control-close" #click.prevent="close">OK</button>
</div>
</div>
</div>
</div>
<!-- end success -->
</template>
<script>
/* eslint-disable no-undef */
export default {
name: 'SuccessMsg',
props: {
title: ''
},
data () {
return {
successMessage: 'success'
}
},
methods: {
show: function (message) {
// in this line I'm getting undefined in console
console.log(this.successMessage)
// this.successMessage = message
$('#message-box-success').addClass('open')
},
close: function () {
$('#message-box-success').removeClass('open')
}
}
}
</script>
I have no problem in the other normal pages but in the component I couldn't access data.
Please help me to resolve this issue.
Thanks in advance
Thank you #IsraGab for your response and the code.
Your are right it's working but there is another problem that I didn't ask correctly.
It's not working when I'm calling the component method from main app in incorrect way.
After a day searching I find the solution.
Using Component Refs
The correct way to calling method is:
this.$refs.errMsg.show('some messages')
Where we have component tag like this:
<v-error ref="errMsg"></v-error>
Thanks again to all

OpenID-Connect-Java-Spring-Server CORS Disabled ERROR

I just started using oidc-client-js, so i am really confused trying to understand it . I have the below question :) .
I have been connected to a remote webserver running OpenIDConnect and specifically using https://github.com/mitreid-connect/OpenID-Connect-Java-Spring-Server i have builded the openid-connect-server-webapp and created a client correctly. It is hosted on a vm .
I followed this tutorial -> link
Link of 3 html files i modified for the tutorial i followed ->
here
The error that is shown on the console:
All good as you can see on the image below , i authorized the simple javascript app and i am getting back the access_token along with id_token , though when i am trying to call the API , boom i get error and i don't know why ?
The html index code i have is ( in case it helps you ) :
<!DOCTYPE html>
<html>
<head>
<title>JS Application</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="node_modules/bootstrap/dist/css/bootstrap.css" />
<style>
.main-container {
padding-top: 70px;
}
pre:empty {
display: none;
}
</style>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">JS Application</a>
</div>
</div>
</nav>
<div class="container main-container">
<div class="row">
<div class="col-xs-12">
<ul class="list-inline list-unstyled requests">
<li>Home</li>
<li><button type="button" class="btn btn-default js-login">Login</button></li>
<li><button type="button" class="btn btn-default js-call-api">Call API</button></li>
<li><button type="button" class="btn btn-danger js-logout">Logout</button></li>
</ul>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="panel panel-default">
<div class="panel-heading">User data</div>
<div class="panel-body">
<pre class="js-user"></pre>
</div>
</div>
</div>
<div class="col-xs-6">
<div class="panel panel-default">
<div class="panel-heading">API call result</div>
<div class="panel-body">
<pre class="js-api-result"></pre>
</div>
</div>
</div>
</div>
</div>
<script src="node_modules/jquery/dist/jquery.js"></script>
<script src="node_modules/bootstrap/dist/js/bootstrap.js"></script>
<script src="node_modules/oidc-client/dist/oidc-client.js"></script>
<script>
// helper function to show data to the user
function display(selector, data) {
if (data && typeof data === 'string') {
data = JSON.parse(data);
}
if (data) {
data = JSON.stringify(data, null, 2);
}
$(selector).text(data);
}
var settings = {
authority: 'http://snf-761523.vm.okeanos.grnet.gr:8080/openid-connect-server-webapp',
client_id: 'client',
client_secret: "secret",
user_id: "user",
popup_redirect_uri: 'http://localhost/jsApp/popup.html',
silent_redirect_uri: 'http://localhost/jsApp/silent-renew.html',
post_logout_redirect_uri: 'http://localhost/jsApp/index.html',
response_type: 'token id_token',
scope: 'openid profile email offline_access',
filterProtocolClaims: false
};
var manager = new Oidc.UserManager(settings);
var user;
Oidc.Log.logger = console;
manager.events.addUserLoaded(function (loadedUser) {
user = loadedUser;
display('.js-user', user);
});
manager.events.addSilentRenewError(function (error) {
console.error('error while renewing the access token', error);
});
manager.events.addUserSignedOut(function () {
alert('The user has signed out');
});
$('.js-login').on('click', function () {
manager
.signinPopup()
.catch(function (error) {
console.error('error while logging in through the popup', error);
});
});
$('.js-call-api').on('click', function () {
var headers = {};
if (user && user.access_token) {
headers['Authorization'] = 'Bearer ' + user.access_token;
}
$.ajax({
url: 'http://snf-761523.vm.okeanos.grnet.gr:8080/openid-connect-server-webapp/api/tokens/access',
method: 'GET',
dataType: 'json',
headers: headers
}).then(function (data) {
display('.js-api-result', data);
}).catch(function (error) {
display('.js-api-result', {
status: error.status,
statusText: error.statusText,
response: error.responseJSON
});
});
});
$('.js-logout').on('click', function () {
manager
.signoutRedirect()
.catch(function (error) {
console.error('error while signing out user', error);
});
});
</script>
</body>
</html>
There is a temporary solution tough only for testing your application and not for production , disabling Web-Security on Google Chrome
FIRST YOU NEED TO KILL ALL THE INSTANCES OF CHROME , then install a Plugin Called CORS Toggle
and finally run the bellow commants from Terminal or Commant Prompt
For Windows
.\chrome --args --disable-web-security --user-data-dir
For Ubuntu Linux (tested only there)
/opt/google/chrome/google-chrome --args --disable-web-security --user-data-dir

Categories