so I'm using vue-meta library to add meta tag to my vue project, and now I'm trying to add my meta from API response, this is what i got from API if i did console.log('response.data.data')
0:
meta_tags_content: "my content"
meta_tags_id: 3
meta_tags_properties: "my property"
__ob__: Observer {value: {…}, dep: Dep, vmCount: 0}
get meta_tags_content: ƒ reactiveGetter()
set meta_tags_content: ƒ reactiveSetter(newVal)
get meta_tags_id: ƒ reactiveGetter()
set meta_tags_id: ƒ reactiveSetter(newVal)
get meta_tags_properties: ƒ reactiveGetter()
set meta_tags_properties: ƒ reactiveSetter(newVal)
__proto__: Object
1:
meta_tags_content: "content"
meta_tags_id: 4
meta_tags_properties: "title"
__ob__: Observer {value: {…}, dep: Dep, vmCount: 0}
get meta_tags_content: ƒ reactiveGetter()
set meta_tags_content: ƒ reactiveSetter(newVal)
get meta_tags_id: ƒ reactiveGetter()
set meta_tags_id: ƒ reactiveSetter(newVal)
get meta_tags_properties: ƒ reactiveGetter()
set meta_tags_properties: ƒ reactiveSetter(newVal)
__proto__: Object
length: 2
I'm trying to add the meta_tags_content and meta_tags_properties to my vue meta tag function (https://www.npmjs.com/package/vue-meta), this is my meta tag function
export default {
name: 'App',
metaInfo () {
return {
title: 'Tiarapot',
meta: [
{
name: 'description',
content: 'Memang canggih (harus ganti)'
},
{
property: 'og:title',
content: 'Website Tiarapot (harus ganti)'
},
{
property: 'og:site-name',
content: 'Tiarapot'
},
{
property: 'og:type',
content: 'website'
},
{
name: 'robots',
content: 'index,follow'
}
]
}
},
}
and what I'm trying to do is to make it like this
export default {
name: 'App',
metaInfo () {
return {
title: 'Tiarapot',
meta: arrayOfConvertedresponse
}
},
}
how to convert those response of array to a meta structured object ?
expected result if i console.log(arrayOfConvertedresponse) is
[
{
property: "my properties",
content: "my content"
},
{
property: "title",
content: "content"
}
]
If you want to use responsive data in metaInfo, you'll need to assign the array to a data property and refer to it in the metaInfo function
export default {
name: 'App',
data: () => ({
arrayOfConvertedresponse: [] // define initial properties
}),
metaInfo () {
return {
title: 'Tiarapot',
meta: this.arrayOfConvertedresponse
}
},
async created () {
// load data from the API
const response = await axios.get("/api/meta-tags")
// map response to the appropriate format and assign to your data property
this.arrayOfConvertedresponse = response.data.data.map(meta => ({
property: meta.meta_tags_properties,
content: meta.meta_tags_content
}))
}
}
See https://vue-meta.nuxtjs.org/faq/async-action.html
Related
I have a login form and where the inputs (email & password) are bound. On clicking the button to submit the form, it prevents the default behaviour and uses the login method defined in the Login.vue; Scripts.
While consoling in Login.vue; Scripts; login method, the form data printed out the {email: 'email', password: 'password'} object (desired). Once it is passed to the action (await this.signIn(this.form)), it consoled out a Vue component all of the sudden. I don't understand why this happened and how can this be solved?
Login.vue Component
Form
<form #submit.prevent="login" method="POST">
<input
type="text"
v-model="form.email"
/>
<input
type="password"
v-model="form.password"
/>
<button class="btn btn-primary">Login</button>
</form>
Scripts
<script>
import { mapActions } from 'vuex'
export default {
data() {
return {
form: {
email: '',
password: '',
},
}
},
computed: {
...mapActions('auth', ['signIn']),
},
methods: {
async login() {
/***************************************
* *
* Print out the form data object *
* *
****************************************/
console.log(this.form)
await this.signIn(this.form)
},
},
}
</script>
Vuex - Auth Module
export const actions = {
signIn({ dispatch, commit }, form) {
/***************************************************************
* *
* Print out a Vue component instead of the passed object *
* *
****************************************************************/
console.log(form)
Auth.signInWithEmailAndPassword(form.email, form.password)
.then(user => {
commit('SET_AUTHENTICATED', true)
commit('SET_USER', user.user)
this.$router.push('/')
})
.catch(err => {
console.log(err)
})
},
}
Console logged content
VueComponent {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$attrs: (...)
$children: []
$createElement: ƒ (a, b, c, d)
$el: div
$listeners: (...)
$options: {parent: VueComponent, _parentVnode: VNode, propsData: undefined, _parentListeners: undefined, _renderChildren: undefined, …}
$parent: VueComponent {_uid: 3, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
$refs: {}
$root: Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
$scopedSlots: {$stable: true, $key: undefined, $hasNormal: false}
$slots: {}
$store: Store {_committing: false, _actions: {…}, _actionSubscribers: Array(1), _mutations: {…}, _wrappedGetters: {…}, …}
$vnode: VNode {tag: "vue-component-4", data: {…}, children: undefined, text: undefined, elm: div, …}
form: (...)
login: ƒ ()
signIn: (...)
__VUE_DEVTOOLS_UID__: "1:4"
_c: ƒ (a, b, c, d)
_computedWatchers: {signIn: Watcher}
_data: {__ob__: Observer}
_directInactive: false
_events: {hook:beforeDestroy: Array(1)}
_hasHookEvent: true
_inactive: null
_isBeingDestroyed: false
_isDestroyed: false
_isMounted: true
_isVue: true
_renderProxy: Proxy {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_routerRoot: Vue {_uid: 2, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
_self: VueComponent {_uid: 4, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
_staticTrees: null
_uid: 4
_vnode: VNode {tag: "div", data: undefined, children: Array(2), text: undefined, elm: div, …}
_watcher: Watcher {vm: VueComponent, deep: false, user: false, lazy: false, sync: false, …}
_watchers: (2) [Watcher, Watcher]
$data: (...)
$isServer: (...)
$props: (...)
$route: (...)
$router: (...)
$ssrContext: (...)
get $attrs: ƒ reactiveGetter()
set $attrs: ƒ reactiveSetter(newVal)
get $listeners: ƒ reactiveGetter()
set $listeners: ƒ reactiveSetter(newVal)
get form: ƒ proxyGetter()
set form: ƒ proxySetter(val)
__proto__: Vue
As Sumurai8 mentioned, I only need to put the ...mapActions('auth', ['signIn']) in methods and not in computed.
methods: {
...mapActions('auth', ['signIn']),
async login() {
console.log(this.form)
await this.signIn(this.form)
},
},
I'am trying to find the keys in an object in javascript.
_relatedRecords: Object { }
_store: Object { _source: {…}, _cache: {…}, __OWNER__ember15756161564291396511861164__: {…} }
identity: Object { type: "something", id: "1" }
<prototype>: {…}
constructor: function Policy()
description:
modifiedtime:
name:
<get description()>: function CPGETTER_FUNCTION()
<set description()>: function CPSETTER_FUNCTION()
length: 1
name: "CPSETTER_FUNCTION"
prototype: Object { … }
<prototype>: function ()
<get modifiedtime()>: function CPGETTER_FUNCTION()
<set modifiedtime()>: function CPSETTER_FUNCTION()
<get name()>: function CPGETTER_FUNCTION()
<set name()>: function CPSETTER_FUNCTION()
<prototype>: Object { … }
This is the object. When I use Object.keys() I get the key values as ['_relatedRecords','_store','identity'] but the values that I need to fetch are the keys ['description','modifiedTime','name'].
I can access them using object.name or object.description and I get these values alright. But how do we go about fetching what all are the keys in the object.
Creating a html table using multiple javascript methods in ReactJS. Object.keys is used to pull the data from objects. Having an issue with rendering the thead th's and tbody tr and td's without getting message, 'Expected an assignment or function call and instead saw an expression no-unused-expressions'.
import React from 'react';
const CreateTable = ({ results }) => {
//headers should be based on keys
const CreateHeaders = () => {
return (
<thead>
<tr>
{Object.keys(results.header).forEach(function(column){
// console.log(column);
<td>
{column}
</td>
})}
</tr>
</thead>
)
}
const CreateBody = ( ) => {
return (
<tbody>
{Object.keys(results.data).forEach(function(tr){
// console.log(results.data[tr])
<tr>
{CreateRows(results.data[tr])}
</tr>
})}
</tbody>
)
}
const CreateRows = (tr) => {
return(
Object.keys(tr).forEach(function(td){
console.log(tr[td]);
<td>{tr[td]}</td>
}));
}
if( results.data !== null && results.data !== undefined){
console.log(<table>{CreateHeaders()}{CreateBody()}</table>);
return <table>{CreateHeaders()}{CreateBody()}</table>
}
else {
return (null);
}
}
export { CreateTable }
I expect a table to render but instead i receive a message stating,
Line 12: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 26: Expected an assignment or function call and instead saw an expression no-unused-expressions
Line 38: Expected an assignment or function call and instead saw an expression no-unused-expressions
I could set a return inside the object.keys function but when i do nothing is rendered but the skeleton of the table. IE
<table><thead></thead><tbody></tbody></table>
Console.log output from if statement towards the bottom of code shown above
{$$typeof: Symbol(react.element), type: "table", key: null, ref: null, props: {…}, …}
$$typeof: Symbol(react.element)
key: null
props:
children: Array(2)
0:
$$typeof: Symbol(react.element)
key: null
props:
children:
$$typeof: Symbol(react.element)
key: null
props: {children: undefined}
ref: null
type: "tr"
_owner: FiberNode {tag: 0, key: null, elementType: ƒ, type: ƒ, stateNode: null, …}
_store: {validated: true}
_self: null
_source: {fileName: "...\src\components\table.js", lineNumber: 10}
__proto__: Object
__proto__: Object
ref: null
type: "thead"
_owner: FiberNode {tag: 0, key: null, elementType: ƒ, type: ƒ, stateNode: null, …}
_store: {validated: true}
_self: null
_source: {fileName: "...\src\components\table.js", lineNumber: 9}
__proto__: Object
1:
$$typeof: Symbol(react.element)
key: null
props: {children: undefined}
ref: null
type: "tbody"
_owner: FiberNode {tag: 0, key: null, elementType: ƒ, type: ƒ, stateNode: null, …}
_store: {validated: true}
_self: null
_source: {fileName: "...\src\components\table.js", lineNumber: 24}
__proto__: Object
length: 2
__proto__: Array(0)
__proto__: Object
ref: null
type: "table"
You're using forEach which has no return value. You're looking for map instead.
<tr>
{Object.keys(results.header).map(column => (
// console.log(column);
<td>
{column}
</td>
))}
</tr>
And return the result of map from CreateRows
const CreateRows = (tr) => {
return(
Object.keys(tr).map(td =>
<td>{tr[td]}</td>
));
}
I have initial state as
sites = [
{id, name, vehicles[], drivers[]},
{id, name, vehicles[], drivers[]},
{id, name, vehicles[], drivers[]},
{id, name, vehicles[], drivers[]},
];
I'm trying to add a vehicle to a given site when selected from a list which is in a component SiteVehcleSelection and the method that handles the selection is:
handleVehicleSelection = (event) => {
const vehicle = this.props.vehicles.find((v) => v.id === parseInt(event.target.dataset.id, 10));
this.props.handleVehicleSelection(event, this.state.site.id, {...vehicle});
};
which passes it up to parent SiteList method:
handleVehicleSelection = (event, siteId, vehicle) => {
this.props.dispatch(siteActions.handleVehicleSelect(siteId, vehicle), event.target.checked);
}
called from the SiteList class:
export function handleVehicleSelect(siteId, vehicle, cmd){
return (dispatch) => {
debugger;
return fetch(`${BASE_URL}/accounts/site-vehicle-action/${siteId}/${vehicle.id}/${cmd}`, {
method: 'PUT',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: ''
}).then((res) => {
return res.json();
}).then((json) => {
if (json.msg === true) {
dispatch(vehicleSelect(siteId, vehicle));
}
});
}
}
which dispatches to this:
export function vehicleSelect(siteId, vehicle){
return {type: actionTypes.ADD_VEHICLE_TO_SITE, siteId, vehicle};
}
and my reducer is:
case actionTypes.ADD_VEHICLE_TO_SITE:
debugger;
const siteIndex = state.findIndex((site) => site.id === action.siteId);
console.log(state);
const newState = [...state.slice(0, siteIndex), {...state[siteIndex], vehicles: [...state[siteIndex].vehicles, action.vehicle],}, ...state.slice(siteIndex +1)];
console.log(newState);
return newState;
when I log before and after the changes have taken place, the vehicle has been added to the correct site but it does not show/refresh in the view here is the logging of the state before and after.
Before change :
0: {drivers: Array(0), id: 1, name: "Site One", vehicles: Array(0)}
1: {drivers: Array(0), id: 2, name: "Site Two", vehicles: Array(0)}
2: {drivers: Array(0), id: 3, name: "Site Three", vehicles: Array(0)}
length: 3
__proto__: Array(0)
After change:
0: {drivers: Array(0), id: 1, name: "Site One", vehicles: Array(1)}
1: {drivers: Array(0), id: 2, name: "Site Two", vehicles: Array(0)}
2: {drivers: Array(0), id: 3, name: "Site Three", vehicles: Array(0)}
length: 3
__proto__: Array(0)
can see the first one had the vehicle added correctly and this is the new state but nothing happens on return as if sitesList does not refresh.
Hope this edit helps explain more.
I think below code will shed some light. I assume you have the corresponding indexes.
let state = [
{ id: "id1", name: "name1", items: [{},{}] },
{ id: "id2", name: "name2", items: [{},{}] },
]
function reducer() {
switch("Action") {
case ADD_SITE: { // add new element to state
return [
...state,
payload.site,
]
}
case ADD_SITE_AT_INDEX: { // add new element to state at index: idx
return [
...state.slice(0, idx),
payload.newSite,
...state.slice(idx)
]
}
case ADD_ITEM: { // add new item to site with index: idx
return [
...state.slice(0, idx),
{
...state[idx],
items: [
...state[idx].items,
payload.newItem
],
},
...state.slice(idx+1)
]
}
case ADD_ITEM_AT_INDEX: { // add new item to site with index: idx, at item index: item_idx
return [
...state.slice(0, idx),
{
...state[idx],
items: [
...state[idx].items.slice(0, item_idx),
payload.newItem,
...state[idx].items.slice(item_idx),
],
},
...state.slice(idx+1)
]
}
}
}
let say this is your structure of state with keys (i am giving random name to the keys so i can explain)
{
data:[{id:"some_id",name:"some_name",items1:[{},{}]}]
}
//suppose this is your reducer code.
case ADD_ITEM:
return{
...state,
data: state.data.map(val=>{
if(val.Id===action.payload.Id){
return{
...val,
items1:[...val.items1,action.payload.data]
}
}
return{...val}
})
}
here you'll be sending Id and data from the action like:
{type:"ADD_ITEM",payload:{Id,data}}
where id will be the id of first level object which's array needs to be updated,
and data will be the data you want to add into the array..
If you just want to add an object to an array with a given structure, you can do this:
Structure
[
{ id, name, items1[{object},{object}]
]
copy an existing state and then add a new object to the end of the array.
return {
...state,
items1: state.items1.concat(action.newObject),
};
or with ES6 spread
return {
...state,
items1: [...state.items1, action.newObject],
};
// state: { id, name, items1: [{object},{object},{newObject}] }
I have this initialStore:
const initialState =
{
0:{
screen_name: '1',
props: null,
},
1:{
screen_name: '2',
props: null,
},
2:{
screen_name: '3',
props: null,
},
3:{
screen_name: '4',
props: null,
},
4:{
screen_name: '5',
props: null,
},
}
I want to know how can I modify for example the value state.0.screen_name: 1, while keeping the rest of the original state using ES6?
This is the approach that I have so far:
export const navigationReducer = createReducer(initialState, {
[types.CHANGE_SCREEN_EXPERIMENTAL](state,action){
return{...state[action.id], screen_name:action.screen_name, ...state
};
}
},
);
However, that returns this:
The action.id is 0, it should modify the state[0] element, however, it copied its elements, modified them and placed them on the state object itself instead of the state[0] object.
Desired result:
navigationReducer:{
0: {
props: null,
screen_name: "ad"
}
1:Object
2:Object
3:Object
4:Object
}
I do not want the screen_name nor props to be outside those objects (0,1,2,3,4).
Any ideas are well appreciated.
I found the way to do it using ES6
Here is how:
export const navigationReducer = createReducer(initialState, {
[types.CHANGE_SCREEN_EXPERIMENTAL](state,action){
return{
...state,[action.id]:{
...state[action.id],
screen_name:action.screen_name,
props:action.props,
}
};
}
},
);
This results in:
Thank you very much for your help and time #ibrahimmahrir.