array.some is not a function in My Laravel Vue Js Project - laravel

I Practicing laravel & Vue js project. Here i have a wishlist button.
<button
:class="wishlists.some(wishlist => wishlist.product_id === productId) ? activeClass:deactiveClass"
v-html="wishlists.some(wishlist => wishlist.product_id === productId) ? activeText:deactiveText"
#click="wishlistStatus(productId)" >
</button>
This is working perfectly but this is throwing also 2 errors.
[Vue warn]: Error in render: "TypeError: _vm.wishlists.some is not a function
and
TypeError: _vm.wishlists.some is not a function.
Now How I fix this

To use the 'some' method, your 'wishlists' variable must be an array.
If at the time your component initializes, that variable is not yet an array, then your application is going to crash.
This usually happens when you initialize your variable, for example, to null and then make a call to the server to fetch the data.
data() {
whislists: null,
...
}
There are several ways to fix this:
The simplest is to initialize your variable as an array.
data() {
whislists: [],
...
}
Another way to solve it would be to wait for your variable to become an array and then render your button, You can achieve this using a v-if.
<button
v-if="wishlists && wishlists.length"
:class="wishlists.some(wishlist => wishlist.product_id === productId) ?
activeClass:deactiveClass"
v-html="wishlists.some(wishlist => wishlist.product_id === productId) ?
activeText:deactiveText"
#click="wishlistStatus(productId)" >
</button>
This may be just one of the reasons why your problem occurs.
Other reasons could be:
You are assigning to your variable 'wishlists' data that is not an array without realizing it.

Related

What is the best way to use v-model without using it in the main app.js file?

I was wondering i have this code inside my blade file:
<input type="text" class="form-control" :model="productname" id="name" name="name" aria-describedby="emailHelp" placeholder="Title" value="{{ old('name') }}" required>
and i want to create an 2 way data binding, so when user submitted 3 or more character to get an green background of this input field, but when they are less to get a red background.
I tried to do this with vue-component, but it seems for whatever reason the vue-component does not have access to the main #app id which is assign to the main app blade template in order all vue code to have access to the html code and change it. I have created an vue-component called Upload inside ressources/assests/js/components/Upload.js, but when i write this code:
<template>
</template>
<script>
export default {
data() {
return {
productname: '',
};
},
mounted() {
console.log('Upload component', this.message);
}
}
</script>
and added of course to app.js like that Vue.component('upload-component', require('./components/Upload.vue'));
and run - npm run dev to compile the code i am getting this error:
[Vue warn]: Property or method "productname" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
Whatever when i write this code inside the main app.js file (resources/assests/js/app.js):
const app = new Vue({
el: '#app',
data() {
return {
productname: '',
};
},
});
everything is working fine and i dont get any errors, but i dont want that, as imagine for my website/app i have to have for example 100 v-models and i dont want to put them all inside the main app.js file. Is there other way to do this?
Can i still somehow make it work inside the vue component, so the component can see the v-model and not giving me this error?
If not, can i make it work and use vue inside the blade file something like that?
new Vue({
el: '#form',
data: {
productname: ''
}
});
but this code its not working. Thanks!
It's a bit tricky to make out what you are doing exactly, but your error is related to having no data property 'message', you have only a property called 'productname'.
If you want your component to communicate up to its parents or siblings you should read into emitting events in vue using
this.$emit

How to pass data from Laravel to Vue.js component v-for

How to pass data from Laravel to Vue.js component v-for ?
I have tried the code below:
<my-component
v-for="(event, eventIndex) in {{ $data['events'] }}">
</my-component>
But it returns:
component lists rendered with v-for should have explicit keys.
You don't use curly braces syntax in bindings.
<my-component v-for="(event, eventIndex) in events" />
events array needs to be defined in your vm's data function:
data() {
return {
events: [] // initialize as an empty array if you fetch the data async
}
}
If you want to fetch your event data asynchronously when the page loads, put the ajax call inside the created() hook of your vm:
created() {
$.ajax({ method: 'get', url: 'your/api/to/get/events' })
then((response)=> {this.events = response.data})
}
To solve the warning message Vue is showing you, add a :key="event.id" (if your events have an id property, otherwise any other unique property):
<my-component v-for="(event, eventIndex) in events" :key="event.id" />
The error message clearly says that you should use :key binding:
component lists rendered with v-for should have explicit keys.
<my-component
v-for="(event, eventIndex) in {{ $data['events'] }}" :key="eventIndex">
<!-- You can bind key to unique key, :key="event.id" -->
<!-- However, it's perfectly good to use :key="eventIndex" -->
</my-component>
From a resource: v2.2.0 release
When using v-for with a component, a key is now required. You will likely see a bunch of "soft warnings" when you upgrade, but this does not affect the current behavior of your app.

Setting conditional onClick behaviour in React Component

I'm working on a component where a button (input field of type 'submit') will submitting data once clicked. However, I'd like to introduce a safeguard to show an alert on screen if the input field is blank.
Thinking this would work the same way as it would for component attributes, I've tried variations on the following without much luck:
onClick={props.inputText === ''
?
alert("Text cannot be blank.")
:
(e => props.onSubmit(props.inputText))}/>
I'd rather not run the check inside the onSubmit function in order to isolate updates to the store as far as possible (I'm following a React-Redux structure).
Any idea if and how JSX handles a situation like this?
This should work:
onClick={() => { props.inputText === '' ?
alert("Text cannot be blank.") :
props.onSubmit(props.inputText) }}
You are assigning the value to onClick event, but onclick expect a function. To achieve that wrap all the logic inside a function body.
Write it like this:
onClick={ e => {
props.inputText === '' ?
alert("Text cannot be blank.")
:
props.onSubmit(props.inputText)}
}
/>
Or
onClick={this.onClick.bind(this)/>
onClick(e){
if(props.inputText === ''){
alert("Text cannot be blank.");
return;
}
props.onSubmit(props.inputText);
}

How to pass javascript variable from laravel controller to vuejs component

I'm trying to build a page on Laravel 5.4 which contains few data which needs to be manipulated and then sent across the views. My view contains components of the vuejs v2.0. I want those data to be implemented in the components. I tried using the laracasts PHP Vars to JS transformer but unable to get it. I followed the steps by placing "laracasts/utilities": "~2.0" in my composer.json then I added the serviceprovider as mentioned in the documentation, I published the vendor and added the following in config/javascript.php,
'bind_js_vars_to_this_view' => 'Nitseditor.show',
I'm having a dynamic views folder which is currently inside my Nitseditor\home\resources\views Now in my controller I'm having following codes:
public function show()
{
JavaScript::put([
'foo' => 'bar',
'age' => 29
]);
return view(Nitseditor.show);
}
Now first of all it was throwing an error as I see that it was including use MongoDB\BSON\Javascript; then I removed and tried using use JavaScript
Now in the app.js file which is present in my asset folder, I'm including each components and trying to do console.log(foo); but its throwing an error foo not defined.
There are a few ways to do this depending on what you are trying to achieve and how your project is set up. The simplest way is to make a request to your controller from inside your component that returns json. Laravel 5.4 comes with axios so you can use that:
methods: {
getData(){
axios.get('/controller/route')
.then(response => {
// set your variables from the response
this.myData = response.data;
})
.catch(error => {
console.log(error);
});
},
data(){
return {
myData: {}
}
}
If you need child components to access the data then you would need to put that in the parent and pass myData" using props.
You could also create a directive and pass your variable down directly from your blade template:
Vue.directive('init', {
bind: function(el, binding, vnode) {
vnode.context[binding.arg] = binding.value;
}
});
Then you would just need to do:
<div v-init:vars="{foo: 'foo', age: 29}"></div>
And pass vars as props to any component that needs them:
Here's the JSFiddle: https://jsfiddle.net/3e05qwLh/
If you have multiple descendants that rely on your variables you will probably want to look at using vuex.
Dunno if it helps but I use this method for passing variables to javascript:
// in master layout (head section)
<meta name="foo" content="{{ $foo }}">
// in javascript (included or in the template)
foo = $('meta[name=foo]').attr('content');
If you have javascript in the blade template you can use directly this method:
foo = "{{ $foo }}";

React 0.14.0-RC1 / React-Router 1.0.0-RC1 - Cannot read property 'props' of null

I am working off Alex Bank's "Building a Polling App with Socket IO
and React.js" (Lynda.com), but I am trying to upgrade it to
react-router 1.0.0-RC1.
My github repository can be found here ....
Problem:
When a speaker signs in and creates a presentation, a list of questions successful appears. However, when the speaker clicks on a respective question to emit to the attendees, I receive the error: "Cannot read property 'props' of null" which identifies the error in the Question.js component:
ask(question) {
console.log('this question: ' + JSON.stringify(question));
this.props.emit('ask', question); <--- Console points to this
}
But I do not believe that is the problem per se. I believe the actual problem is that this emit is not reaching the socket.on in the app.
APP.js:
componentWillMount() {
this.socket = io('http://localhost:3000');
this.socket.on('ask', this.ask.bind(this));
....
}
ask(question) {
sessionStorage.answer = '';
this.setState({ currentQuestion: question });
}
I believe it is react-router related, but the parent route does have component {APP}, and Speaker is a child route and the Speaker component does import the Question component, so I am assuming the Question component is connected to the APP's.
In Alex's project it is working, but he uses:
"react": "^0.13.3",
"react-router": "^0.13.3",
Any chance someone can offer me some insight on this?
Many Thanks!
If your error says "Cannot read property 'props' of null," that's exactly what's happening: you're attemping to call .props on a value that is null.
However, the real problem is in this code:
ask(question) {
console.log('this question: ' + JSON.stringify(question));
this.props.emit('ask', question);
}
addQuestion(question, index) {
return (
<div key={ index } className="col-xs-12 col-sm-6 col-md-3">
<span onClick={ this.ask.bind(null, question) }>{ question.q }</span>
</div>
);
}
Specifically, this code (which isn't included in the question):
onClick={ this.ask.bind(null, question) }>
You're assigning a click handler to a version of this.ask that's bound to null; this works fine with React.createClass-type components, because React forcibly and automatically binds all component methods to the component instance, no matter what you pass as the first argument to .bind() (and so null is commonly used; I think React actually yells at you otherwise). However, this is not the case with ES6 classes; you're literally setting this inside ask() to null.
A correct version would be
onClick={ this.ask.bind(this, question) }>
or, commonly, as an anonymous function
onClick={ () => this.ask(question) }>
The error message indicates this is null. The reason is react doesn't autobind this to the react element. That is, the this doesn't reference to the element itself while invoking ask(question) method. You only have to bind it in the constructor: this.ask = this.ask.bind(this). It's better for you to read the ES6 class notes on official react blog.
Reading react-router upgrade guide is also a good idea :)

Resources