I'm writing el-tree using vuejs,it doesn't select what i checked - vue.js

I'm writing el-tree using vuejs,it doesn't select what i checked.
anyone knows why?
enter image description here
<el-tree
class="tree-border"
:data="menuOptions"
show-checkbox
ref="menu"
node-key="id"
:check-strictly="form.menuCheckStrictly"
empty-text="Loading, please wait"
:props="defaultProps"
></el-tree>
created() {
this.handleUpdate();
const userId = this.$route.params && this.$route.params.userId;
if (userId) {
getAuthUserMenu(userId).then((response) => {
this.form = response.user;
this.$nextTick(() => {
let checkedKeys = response.checkedKeys
checkedKeys.forEach((value) => {
this.$nextTick(()=>{
this.$refs.menu.setChecked(value, true ,false);
})
})
});
});
}
},
I try to select from the tree component.
I expect that seleted what i choose.

Related

how to get axios to load when row is expanded?

I have a dynamic table that has two axios.get methods. My methods work and the data get added to the table but I would like networkGroup to load only when I click toggle to expand a row. I can only get NetworkGroup to load automatically. How do I get it to work?
Here is my code:
toggle(gpId)
{
this.$set(this.networkGroups[audId], 'isExpanded', !this.networkGroups[gpId].isExpanded);
},
async getData(currPage)
{
const skip = (currPage - 1) * this.page.top;
const response = await this.axios.get(`/s/groups`, {
params: {
skip: skip,
top: this.page.top,
},
});
this.page = response.data.pages;
for (const audience of response.data.data)
await this.getNetworks(group.id);
this.groups = response.data.data;
},
async getNetworks(audId)
{
try
{
const response = await this.axios.get("/s/groups/network-groups?gpId=" + gpId);
if (!this.networkGroups[gpId])
{
this.$set(this.networkGroups, gpId, {});
this.$set(this.networkGroups[gpId], 'isExpanded', false);
}
this.$set(this.networkGroups[audId], 'data', response.data ? response.data.data : []);
}
catch (error)
{
if (error.message && error.message.includes("404"))
{
if (!this.networkGroups[gpId])
{
this.$set(this.networkGroups, gpId, {});
this.$set(this.networkGroups[gpId], 'isExpanded', false);
}
this.$set(this.networkGroups[gpId], 'data', []);
}
else
{
console.log(error.message);
}
}
},
<td class="audience-column">
<!-- expand button -->
<div class="ex_btn">
<span #click.prevent="toggle(group.id)">
<font-awesome-icon
:icon="
(networkGroups[group.id].isExpanded)
? 'caret-down'
: 'caret-right'
"
:class="[
'dropdown--arrow fa-2x cl-blue-primary relative t-3 g-link',
]"
/>
</span>
</div>
</td>
Not sure what I should change. Thanks!
seems it's not calling anything whenever you toggle the expand button, toggle method should call the getNetwork methods
try this:
toggle(gpId) {
this.$set(this.networkGroups[audId], 'isExpanded', !this.networkGroups[gpId].isExpanded); <<<--- change this
this.getNetwork(gpId) <<-- into this
},
and i think you set the wrong argument on getNetwork method:
getNetworks(audId) <<--- it says audId
{
try
{
const response = await this.axios.get("/s/groups/network-groups?gpId=" + gpId); <<--- but this calls gpId
....
hope my answer helps you!

Reordering Array for Todos in MST Mobx State Tree

I would like to reorder arrays when using mobx state tree.
Say I have this example taken from the example page.
How do I get to reorder my ToDos in the TodoStore.
As a simplified example, say my todos are ['todo1, todo2'], how do I change them so that the new array is ['todo2, todo1']?
const Todo = types
.model({
text: types.string,
completed: false,
id: types.identifierNumber
})
.actions((self) => ({
remove() {
getRoot(self).removeTodo(self)
},
edit(text) {
if (!text.length) self.remove()
else self.text = text
},
toggle() {
self.completed = !self.completed
}
}))
const TodoStore = types
.model({
todos: types.array(Todo),
filter: types.optional(filterType, SHOW_ALL)
})
.views((self) => ({
get completedCount() {
return self.todos.filter((todo) => todo.completed).length
},
}))
.actions((self) => ({
addTodo(text) {
const id = self.todos.reduce((maxId, todo) => Math.max(todo.id, maxId), -1) + 1
self.todos.unshift({ id, text })
},
removeTodo(todo) {
destroy(todo)
},
}))
export default TodoStore
Thanks a lot!
If you want move the second todo to the first index in the array you could create a new action and splice the second todo out and then unshift it back in:
swapFirstTwoTodos() {
const secondTodo = self.todos.splice(1, 1)[0];
self.todos.unshift(secondTodo);
}

BootstrapVue b-table toggleDetails opens multiple row details

I have an issue with Bootstrap Vue table showDetails for row.
When I open website for the first time and I click show details button it shows details with loading state, fetch the data and then when completed shows the details.
However when I hide the expanded row and click show Details for another row, after the fetch both of them are expended. Meaning I can see details of 2 rows.
(If I open and hide X of rows, after I expand one more, all previously opened and hiden X details will be visible)
Thank you for help!
Toggle details Method:
toggleDetails(item) {
if (item._showDetails) {
this.$set(item, '_showDetails', false)
} else if (this.listType === MEETING_LIST_TYPE.history) {
this.$set(item, '_showDetails', true)
} else {
item._showDetails = true
item.busy = true
this.showMeetingDetails({
meeting: item,
listType: this.listType
}).then(() => {
item.busy = false
})
}
}
Fetch method (action):
showMeetingDetails({ commit }, { meeting, listType }) {
return fetchMeetingDetails(meeting).then(res => {
commit('SET_MEETING_DETAILS', { meeting: res, listType })
})
}
Mutation:
SET_MEETING_DETAILS(state, { listType, meeting }) {
switch (listType) {
case MEETING_LIST_TYPE.today:
state.todayMeetings = state.todayMeetings.map(m =>
m.meetingID === meeting.meetingId
? { ...m, ...meeting, _showDetails: true }
: m
)
break
case MEETING_LIST_TYPE.all:
state.allMeetings = state.allMeetings.map(m =>
m.meetingID === meeting.meetingId
? { ...m, ...meeting, _showDetails: true }
: m
)
break
default:
break
}
}
Hello I figure out the solution. :D
So the problem was with vue reactivity when I was trying to change the value for the item which was inside the list and trying to jump over vuex a bit.
Helpful link here:
https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
To solve this problem I added mutations in my vuex for _showDetails and also busy state to show spinner when I am loading details row data. I also found out that in row item from bootstrap table, there are a lot of useful properties like index.
That all helped me to write cleaner mutations with usage of Vue.set()
Bellow my code. Probably I could still fix the methods naming ^^. If you have any ideas how to make it even simpler or cleaner I will appreciate!
Vue template (inside b-table):
<b-button id="detailsBtn" class="mr-2">
<b-icon
#click="toggleDetails(row)"
v-if="!row.detailsShowing"
icon="plus"
></b-icon>
<b-icon v-else icon="dash" #click="toggleDetails(row)"></b-icon>
</b-button>
my toggleDetails() function:
toggleDetails(row) {
if (row.item._showDetails) {
this.hideShowDetails(row, false)
} else {
this.showDetails(row)
}
},
showDetails(row) {
if (this.listType === MEETING_LIST_TYPE.history) {
this.hideShowDetails(row, true)
} else {
this.TOGGLE_BUSY_MEETING({
listType: this.listType,
index: row.index,
isBusy: true
})
this.hideShowDetails(row, true)
this.fetchMeetingDetails({
meeting: row.item,
listType: this.listType,
index: row.index
})
}
},
hideShowDetails(row, showDetails) {
this.TOGGLE_MEETING_DETAILS({
listType: this.listType,
index: row.index,
showDetails: showDetails
})
}
My action:
fetchMeetingDetails({ commit }, { meeting, listType, index }) {
return fetchMeetingDetails(meeting).then(res => {
commit('SET_MEETING_DETAILS', { meeting: res, listType, index })
})
}
My mutations:
SET_MEETING_DETAILS(state, { listType, meeting, index }) {
Vue.set(state.meetings[listType], index, {
...state.meetings[listType][index],
...meeting,
_showDetails: true,
busy: false
})
},
TOGGLE_MEETING_DETAILS(state, { listType, index, showDetails }) {
Vue.set(state.meetings[listType], index, {
...state.meetings[listType][index],
_showDetails: showDetails
})
},
TOGGLE_BUSY_MEETING(state, { listType, index, isBusy }) {
Vue.set(state.meetings[listType], index, {
...state.meetings[listType][index],
busy: isBusy
})
}
I hope someone might find it helpful! Cheers!

(AppsFlyer / ReactNative) How can I get attribution parameter from onAppOpenAttribution?

This might be a dumb question, but currently I really need a help. Can someone please help me out?
I'm implementing AppsFlyer on my ReactNative Project (Android)
What I want to do is console.log attribution parameter.
But, there are no console.logging happening.
Could someone please read my snippet and how can I access to attribution parameter, please?
or, is there any proper way to console.log attribution parameter or save it to variable?
App.tsx
​import appsFlyer from 'react-native-appsflyer';
var testFunc = appsFlyer.onAppOpenAttribution(
    (data) => {
        console.log(data);
    }
);
appsFlyer.initSdk(
    {
        devKey: '***************************',
        isDebug: false,
    },
    (result) => {
        console.log(result);
    },
    (error) => {
        console.error(error);
    },
);
const Home: React.FC<Props> = props => {
    const [appState, setAppState] = useState(AppState.currentState);
    // ! when I press device's home button (appstate changes to background),
   // ! console.log in testFunc is not working...
  
    useEffect(() => {
        function handleAppStateChange(nextAppState) {
            if (appState.match(/active|foreground/) && nextAppState === 'background') {
                if (testFunc) {
                    testFunc();
                    testFunc = null;
                }
            }
          setAppState(nextAppState);
       }
        AppState.addEventListener('change', handleAppStateChange);
        return () => {
        AppState.removeEventListener('change', handleAppStateChange);
      };
  })
To my understanding, the onAppOpenAttribution event only triggers when you already have the app installed and click on a deep link. Try to use onInstallConversionData instead and see what happens, since it triggers once the SDK is initialized. I'd also remove the "useEffect" section entirely just to test. I hope this helps.
nevermind,
I added appsFlyer.onInstallConversionData
then it worked...
import appsFlyer from 'react-native-appsflyer';
var onInstallConversionDataCanceller = appsFlyer.onInstallConversionData((res) => {
if (JSON.parse(res.data.is_first_launch) == true) {
if (res.data.af_status === 'Non-organic') {
var media_source = res.data.media_source;
var campaign = res.data.campaign;
console.log('This is first launch and a Non-Organic install. Media source: ' + media_source + ' Campaign: ' + campaign);
} else if (res.data.af_status === 'Organic') {
console.log('This is first launch and a Organic Install');
}
} else {
console.log('This is not first launch');
}
});
var onAppOpenAttributionCanceller = appsFlyer.onAppOpenAttribution((res) => {
console.log(res)
});
appsFlyer.initSdk(
{
devKey: '***************************',
isDebug: false,
},
(result) => {
console.log(result);
},
(error) => {
console.error(error);
},
);
const Home: React.FC<Props> = props => {
const [appState, setAppState] = useState(AppState.currentState);
useEffect(() => {
function handleAppStateChange(nextAppState) {
if (appState.match(/active|foreground/) && nextAppState === 'background') {
if (onInstallConversionDataCanceller) {
onInstallConversionDataCanceller();
onInstallConversionDataCanceller = null;
}
if (onAppOpenAttributionCanceller) {
onAppOpenAttributionCanceller();
onAppOpenAttributionCanceller = null;
}
}
AppState.addEventListener('change', handleAppStateChange);
return () => {
AppState.removeEventListener('change', handleAppStateChange);
};
})

Delete method with vue-tags-input Vue Js

I try to create a delete method in vue-tags-input in Vue Js. I am not sure how to get the index. from this tag. Usually in my delete method I use the index .
<vue-tags-input
v-model="tagName"
class="tags-input w-100 mt-0"
#before-deleting-tag="deleteCustomerName"
/>
deleteCustomerName: function () {
const id = this.editedItemId;
const id_c = 33; //right now I am not sure how to get id_c
// const deleted_user_name = this.customer_names[index].name;
this.boxOne = "";
this.$bvModal
.msgBoxConfirm("Are you sure that you want to delete this ?", {
okVariant: "danger",
okTitle: "Delete",
cancelTitle: "Cancel",
centered: true
})
.then(confirm => {
if (confirm) {
deleteApi("/customers/" + id + "/" + id_c).then(() => {
this.$nextTick(() => {
// this.$emit('deleted',deleted_user_name)
// this.customer_names.splice(index, 1); //usualy I do this, but now it doesn't now how index is
console.log('User deleted!');
});
});
}
})
.catch(error => {
console.log(error);
});
},
Here is describing http://www.vue-tags-input.com/#/api/events . before-deleting-tag return index,tag,deleteTag[func] so you need to set param in deleteCustomerName parameters scope .
deleteCustomerName: function (params) {
console.log(params.index)
....
}