Bad response with axios call in laravel - javascript

I'm trying to figure out what's going on here, but I've set my Vue instance to hit an axios call every time a new tag is added. The problem is I keep getting a 400 bad request and I can't figure out why.
When I add a tag and inspect my Vue element, my object is tag_data: "test string". I just want to make the call with "test string" as my data.
Any obvious issues with what I'm doing?
Route
Route::post('tags/save','CampaignsController#saveTags')
->name('tags/save');
Controller
public function saveTags(Request $request)
{
$tagData = $request->tag_data;
$stmt->bindValue(1,$tagData, PDO::PARAM_STR);
$stmt->bindParam(2, $out2, PDO::PARAM_INT|PDO::PARAM_INPUT_OUTPUT);
$stmt->execute();
}
Blade
new Vue({
components: {
Multiselect: window.VueMultiselect.default
},
el: "#tagApp",
data() {
return{
value: [],
loading: false,
options: []
}
},
methods: {
read: function(val){
if (val) {
this.loading = true;
this.options = [];
} else {
this.options = [];
}
},
/*Issue is here*/
addTag(newTag) {
const tag = {
tag_data: newTag,
};
this.options.push(tag);
this.value.push(tag);
axios.post('campaigns/tags/save',{
tag_data: newTag,
})
.then(function (response){
console.log(response);
})
.catch(function (error) {
console.log(error);
console.log(tag_data);
});
}
}
})

Related

Pinia|Vue3 I can't access the property of the object that returned from the Pinia action

first of all I am using the Mockjs to simulate the backend data:
{
url: "/mockApi/system",
method: "get",
timeout: 500,
statusCode: 200,
response: { //
status: 200,
message: 'ok',
data: {
'onlineStatus|3': [{
'statusId': '#integer(1,3)',
'onlineStatusText': '#ctitle(3)',
'onlineStatusIcon': Random.image('20*20'),
'createTime': '#datetime'
}],
'websiteInfo': [{
'id|+1': 1,
}]
}
}
}
the data structure would be: https://imgur.com/a/7FqvVTK
and I retrieve this mock data in Pinia store:
import axios from "axios"
import { defineStore } from "pinia"
export const useSystem = defineStore('System', {
state: () => {
return {
systemConfig: {
onlineStatus: [],
},
}
},
actions: {
getSystemConfig() {
const axiosInstance = axios.interceptors.request.use(function (config) {
// Do something before request is sent
config.baseURL = '/mockApi'
return config
}, function (error) {
// Do something with request error
return Promise.reject(error);
})
axios.get('/system/').then(res => {
this.systemConfig.onlineStatus = res.data.data.onlineStatus
})
// console.log(res.data.data.onlineStatus)
axios.interceptors.request.eject(axiosInstance)
}
}
})
I use this store in the parent component Profile.vue:
export default {
setup() {
const systemConfigStore = useSystem()
systemConfigStore.getSystemConfig()
const { systemConfig } = storeToRefs(systemConfigStore)
return {
systemConfig,
}
},
computed: {
getUserOnlineStatusIndex() {
return this.userData.onlineStatus//this would be 1-3 int.
},
getUserOnlineStatus() {
return this.systemConfig.onlineStatus
},
showUserOnlineStatusText() {
return this.getUserOnlineStatus[this.getUserOnlineStatusIndex - 1]
},
},
components: {UserOnlineStatus }
}
template in Profile.vue I import the child component userOnlineStatus.vue
<UserOnlineStatus :userCurrentOnlineStatus="userData.onlineStatus">
{{ showUserOnlineStatusText }}
</UserOnlineStatus>
here is what I have got https://imgur.com/fq33uL8
but I only want to get the onlineStatusText property of the returned object, so I change the computed code in the parent component Profile.vue:
export default {
setup() {
const systemConfigStore = useSystem()
systemConfigStore.getSystemConfig()
const { systemConfig } = storeToRefs(systemConfigStore)
return {
systemConfig,
}
},
computed: {
getUserOnlineStatusIndex() {
return this.userData.onlineStatus//this would be 1-3 int.
},
getUserOnlineStatus() {
return this.systemConfig.onlineStatus
},
showUserOnlineStatusText() {
return this.getUserOnlineStatus[this.getUserOnlineStatusIndex - 1]['onlineStatusText']//👀I chage it here!
},
},
components: {UserOnlineStatus }
}
but I will get the error in the console and it doesn't work:
https://imgur.com/Gb68Slk
what should I do if I just want to display the specific propery of the retrived data?
I am out of my wits...
I have tried move the store function to the child components, but get the same result.
and I google this issue for two days, nothing found.
Maybe it's because of I was trying to read the value that the Profile.vue hasn't retrieved yet?
in this case, how could I make sure that I have got all the value ready before the page rendered in vue3? Or can I watch this specific property changed, then go on rendering the page?
every UX that has data is coming from remote source (async data) should has spinner or skeleton.
you can use the optional chaining for safe access (if no time to await):
return this.getUserOnlineStatus?.[this.getUserOnlineStatusIndex - 1]?.['onlineStatusText']

apollo client offsetLimitPagination not working

I have a hook..
export function useLazyProposalList() {
const [getQueueData, { loading, data, error, fetchMore }] = useLazyQuery(PROPOSAL_LIST, {
fetchPolicy: 'no-cache',
});
const proposalList = React.useMemo(() => {
if (!data) {
return null;
}
return transformProposals(data);
}, [data]);
return {
getQueueData,
fetchMore,
loading,
data: proposalList,
error,
};
}
In the component
const {
getQueueData,
data: queueData,
fetchMore: fetchMoreProposals,
// loadMore: loadMore,
} = useLazyProposalList();
If user clicks on fetch more button, I call: fetchMoreProposals .
await fetchMoreProposals({
variables: {
offset: visibleProposalList.length,
},
});
but this doesn't update my data. I read that we should use offsetLimitPagination, but my data from query is not array itself. It's like this: queue { id: '1', items:[] } and because of this, offsetLimitPagination doesn't work. So I tried merge
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
queue: {
keyArgs: false,
merge(existing, incoming) {
console.log(existing, incoming);
if (!incoming) return existing;
if (!existing) return incoming;
},
},
},
},
}
but in the console, it just prints refs instead of real data.
What could be the issue ?

Unable to pass the required parameters into the URL - Laravel Inertia Vue

I am building a datatable with multi-column sorting functionality. As up to now, the sorting functionality is working fine, what I am unable to get is, right parameters into the url. As I am only passing $sorts to the component, as a prop, hence I'm using this.$inertia.get to pass the $sorts back to the controller, which is returning back the sorted data. But due to passing sorts: this.sorts within the Inertia get method, its returning back the url query as http://127.0.0.1:8000/users?sorts[name]=asc. How can I get the required parameter within the Inertia get method so I get a url query as suchhttp://127.0.0.1:8000/users?sort_field=name&sort_direction=asc as well as pass the $sorts as well so it returns back the expected data.
Controller
public $sorts = [];
public function initalizeSortingRequest()
{
$this->sorts = request()->get('sorts', $this->sorts);
}
public function applySorting($query)
{
foreach ($this->sorts as $sort_field => $sort_direction) {
$query->orderBy($sort_field, $sort_direction);
}
return $query;
}
Component
<script >
methods: {
sortBy(field) {
if (!this.sorts[field]) {
this.sorts[field] = 'asc';
} else if (this.sorts[field] == 'asc') {
this.sorts[field] = 'desc';
} else {
delete this.sorts[field];
}
let route = this.route('users.index', {
sorts: this.sorts
})
this.$inertia.get(route, {}, {
only: ['usersData'],
preserveState: true,
preserveScroll: true
})
}
}
</script>
I recently made a screencast on building a datatable with InertiaJS and Laravel.
The gist of it is:
import AppLayout from '#/Layouts/AppLayout';
import Pagination from '../Jetstream/Pagination';
import { pickBy, throttle } from 'lodash';
export default {
components: {
AppLayout,
Pagination,
},
props: {
users: Object,
filters: Object,
},
data() {
return {
params: {
search: this.filters.search,
field: this.filters.field,
direction: this.filters.direction,
},
};
},
methods: {
sort(field) {
this.params.field = field;
this.params.direction = this.params.direction === 'asc' ? 'desc' : 'asc';
},
},
watch: {
params: {
handler: throttle(function () {
let params = pickBy(this.params);
this.$inertia.get(this.route('users'), params, { replace: true, preserveState: true });
}, 150),
deep: true,
},
},
};
Then in the controller index action:
public function index()
{
request()->validate([
'direction' => ['in:asc,desc'],
'field' => ['in:name,city']
]);
$query = User::query();
if (request('search')) {
$query->where('name', 'LIKE', '%'.request('search').'%');
}
if (request()->has(['field', 'direction'])) {
$query->orderBy(request('field'), request('direction'));
}
return Inertia::render('Users', [
'users' => $query->paginate()->withQueryString(),
'filters' => request()->all(['search', 'field', 'direction'])
]);
}
You can watch the screencast here.

How to push new data input to top on the list

hello how to push new data to the top list using vue.js and laravel, I tried but still failed, I hope someone can help with the problem.
this is my Controller
public function addComment()
{
$this->validate(request(), [
'comment' => 'required',
]);
$comment = [
'comment' => request()->comment,
'article_id' => request()->article_id,
'user_cid' => Auth::user()->user_cid,
];
$comment = ArticleComment::create($comment);
return new ArticleCommentResource($comment);
}
and this is my Vue.js Method
data() {
return {
data: [],
comments:[],
form: new Form({
comment: '',
article_id: this.articleid,
})
}
},
methods: {
onSubmit() {
this.showLoader = true
this.form.post('add-comment')
.then(response => {
console.log(response.article_id);
this.form.article_id = response.article_id;
});
},
}
how to handle it, thank you
I hope someone can help
Assuming your list simply loops through your comments array, you need to push the response at the first position of the list:
onSubmit() {
this.showLoader = true
this.form.post('add-comment')
.then(response => {
this.comments.unshift(response);
});
},
This assumes that response is the actual comment (I can't see into your form class).
<script>
import Form from 'form-backend-validation';
export default {
data:() => ({
form: new Form({
article_id: null,
}),
}),
mounted() {
this.fetch();
},
methods: {
async fetch() {
const response = await this.form.post('add-comment');
this.form.article_id = response.comment.article_id;
}
}
}
</script>
Please try this one.

this.$http.get seems doesn't work vue-resource

uses vue 2.1.10 vue-resource 1.3.4 to fetch the data:
const app = new Vue({
el: '#UserController',
data:{
users : [],
},
methods:{
fetchUser: function(){
this.$http.get('http://localhost:8000/api/api/users', function(data){
this.$set('users',data)
})
}
},
mounted(){
this.fetchUser()
}
});
but in the end
users has no value.
Vue-resource is a promise based API.
The syntax for the get request should be
this.$http.get('/someUrl')
.then(response => {
// get body data
this.someData = response.body;
}, err => {
// error callback
});
Since you have initialized users: [ ] in the data option , no need to use Vue.$set you can directly assign the value using this.users = data
So do it like this:
fetchUser: function(){
this.$http.get('http://localhost:8000/api/api/users')
.then((data) => {
this.users = data;
}, err => {
// handle error
})
}
const app = new Vue({
el: '#UserController',
data:{
users : [],
},
methods:{
fetchUser: function(){
var self = this;
this.$http.get('http://localhost:8000/api/api/users', function(data){
self.$set(self,'users',data)
})
}
},
mounted(){
this.fetchUser()
}
});
Check variable scope. Set pointer to "this" like "self".

Categories

Resources