Nativescript-vue TabView unable to render first item coming from API - javascript

Situation:
Im working on nativescript-vue app where im using TabView Items to create tabs. The title for tab and the information inside the tab is being for looped from JSON data file.
Problem:
The first tabviewitem doesnt render any information. Inorder to see the data, i have to click on other tabs first go back to first tab. After that, i can see the items
The markup i have to create tab using nativescript-vue:
<TabView
android:tabBackgroundColor="#ffffff"
android:tabTextColor="#ffa801"
android:selectedTabTextColor="#f53b57"
androidSelectedTabHighlightColor="#ffffff"
androidTabsPosition="Bottom">
<TabViewItem v-for="subcategory in subcategories" :title="subcategory.name" >
<FlexboxLayout>
<Label :text="subcategory.name" />
</FlexboxLayout>
</TabViewItem>
</TabView>
Subcategories is JSON array coming from API with following structure.
[
{
"id": 3,
"category_id": 1,
"name": "Vegetarian",
"ar_name": null,
"description": "Vegetarian",
"ar_description": null,
"image": null,
"created_at": "2020-03-04 04:12:13",
"updated_at": "2020-03-04 04:12:13",
"items": [
{
"id": 6,
"subcategory_id": 3,
"name": "Salad",
"ar_name": null,
"description": "test",
"ar_description": null,
"price": "100",
"status": "1",
"ar_price": null,
"discount": null,
"discount_colour": null,
"created_at": "2020-05-07 05:32:17",
"updated_at": "2020-05-07 05:32:17"
}
]
},
{
"id": 2,
"category_id": 1,
"name": "Sea Food",
"ar_name": null,
"description": "sea food",
"ar_description": null,
"image": null,
"created_at": "2020-03-04 04:11:38",
"updated_at": "2020-03-04 04:11:38",
"items": [
{
"id": 4,
"subcategory_id": 2,
"name": "some item",
"ar_name": null,
"description": "desc",
"ar_description": null,
"price": "100",
"status": "1",
"ar_price": null,
"discount": null,
"discount_colour": null,
"created_at": "2020-05-06 12:02:58",
"updated_at": "2020-05-06 12:02:58"
}
]
}
]
Solutions that i have tried
https://github.com/nativescript-vue/nativescript-vue/issues/515
but no luck
[Update] here is my script:
<script >
import axios from 'axios';
import Login from "./Login";
import FoodItems from "./FoodItems"
import SubCategories from "./parts/SubCategories"
import CategoryButtons from "./parts/CategoryButtons"
import Popular from "./parts/Popular"
// import Items from "./Items"
export default {
components: {SubCategories, CategoryButtons, Popular},
props: ['parentCategory'],
data() {
return {
subcategories: [],
populars: [],
categories:this.$store.getters.getCategories,
}
},
mounted(){
axios({
method:"GET",
"url":this.$store.state.apiUrl+"categories/"+this.parentCategory.id+"/subcategories",
headers:{
'Accept': 'application/json',
'Authorization': 'Bearer ' + this.$store.getters.getToken,
}
}).then(
response =>
{
//
this.subcategories =response.data.fooditems;
this.populars = response.data.popularitems;
// console.log(response.data.popularitems);
}, error => {
console.error(error);
}
);
},
methods: {
checkToken() {
this.$store.commit("loadFromStorage");
if(!this.$store.getters.getToken) { this.$navigateTo(Login, { clearHistory: true }) }
},
goToShowCase(args) {
// console.log(args);
this.$navigateTo(Showcase,
{
props:
{ parentCategory: args }
});
}
}
}
</script>
Update 2:
I created a similar issue on nativescript playground.
https://play.nativescript.org/?template=play-vue&id=7mNLr7
Thank you in advance!

Does adding a :key to your iterated items solve the issue?
<TabViewItem v-for="subcategory in subcategories"
:key="some_unique_value_between_them"
:title="subcategory.name"
loaded="mainContentLoaded">

Related

Manipulating nested objects

I have the following data structure:
{
"nodes": [
{
"frontmatter": {
"excerpt": null,
"featured": true,
"title": "A Post with Content"
},
"fields": {
"slug": "posts/a-post-of-type-page",
}
},
{
"frontmatter": {
"excerpt": null,
"featured": null,
"title": "A post of type post"
},
"fields": {
"slug": "posts/a-post-of-type-post",
}
},
{
"frontmatter": {
"excerpt": null,
"featured": null,
"title": "Another Post (or type post)"
},
"fields": {
"slug": "posts/another-post-or-type-post",
}
},
{
"frontmatter": {
"excerpt": "This is the excerpt of a post",
"featured": null,
"title": "With Content"
},
"fields": {
"slug": "posts/with-content",
}
},
]
}
I know that I can use myObject.nodes.map(x => x.frontmatter) to bring the frontmatter up a level and removing the nesting. But, I now need to change each node into the following structure within the resulting array:
{
"nodes": [
{
"excerpt": null,
"featured": true,
"title": "A Post with Content"
"slug": "posts/a-post-of-type-page",
},
...
]
}
So, I need to remove the nesting for both the frontmatter and fields.
Thanks
const d = {"nodes":[{"frontmatter":{"excerpt":null,"featured":true,"title":"A Post with Content"},"fields":{"slug":"posts/a-post-of-type-page"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"A post of type post"},"fields":{"slug":"posts/a-post-of-type-post"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"Another Post (or type post)"},"fields":{"slug":"posts/another-post-or-type-post"}},{"frontmatter":{"excerpt":"This is the excerpt of a post","featured":null,"title":"With Content"},"fields":{"slug":"posts/with-content"}}]};
d.nodes = d.nodes.map(({frontmatter, fields})=>({...frontmatter, ...fields}));
console.log(d);
Here is another solution:
const data = {"nodes":[{"frontmatter":{"excerpt":null,"featured":true,"title":"A Post with Content"},"fields":{"slug":"posts/a-post-of-type-page"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"A post of type post"},"fields":{"slug":"posts/a-post-of-type-post"}},{"frontmatter":{"excerpt":null,"featured":null,"title":"Another Post (or type post)"},"fields":{"slug":"posts/another-post-or-type-post"}},{"frontmatter":{"excerpt":"This is the excerpt of a post","featured":null,"title":"With Content"},"fields":{"slug":"posts/with-content"}}]};
let newArr = [];
data.nodes.forEach((n)=>newArr.push(Object.assign(n.fields, n.frontmatter)));
console.log({"nodes": newArr});

TypeORM Select Column from relation without using QueryBuilder

If anyway to select columns from relation without using querybuilder ???
This is my current query:
const areas = await this.areaRepository.find({
where: { ...isActive },
relations: ["division"],
});
Output :
{
"id": 1,
"version": 9,
"isActive": 1,
"createdBy": null,
"updatedBy": 1,
"createAt": "2022-04-18T15:42:12.000Z",
"updatedAt": "2022-09-23T11:04:53.000Z",
"name": "Dhaka",
"division": {
"id": 3,
"version": 1,
"isActive": 1,
"createdBy": null,
"updatedBy": null,
"createAt": "2022-04-18T15:42:00.000Z",
"updatedAt": "2022-04-18T15:42:00.000Z",
"name": "Dhaka"
}
},
But is there anything like:
const areas = await this.areaRepository.find({
select: ['id','division.id division_id']
where: { ...isActive },
relations: ["division"],
});
And the output will be:
{
"id": 1,
"division_id": 3
}
This is a duplicated question of: How to select fields from joined table using TypeORM repository?
You can check the answer here. Also this depends on which TypeOrm version you are currently using, as far as I know on version under 0.3 this doesn't work.

vue js select (vuetify) + axios population

I have a stack with vue js (vuetify) + laravel + axios.
I am trying to populate a dropdown select using axios.
I have setup an API route on laravel so I can pull data from database table "Categories".
The api return the following:
[
{
"id": 1,
"category_name": "Electronics",
"category_synonym": "Computer Accessories",
"created_at": "2020-05-31T20:11:56.000000Z",
"updated_at": "2020-05-31T20:11:56.000000Z"
},
{
"id": 2,
"category_name": "Hardware",
"category_synonym": "hardware",
"created_at": "2020-05-31T20:17:13.000000Z",
"updated_at": "2020-05-31T20:17:13.000000Z"
},
{
"id": 3,
"category_name": "Kitchenware",
"category_synonym": null,
"created_at": "2020-05-31T20:49:32.000000Z",
"updated_at": "2020-05-31T20:49:32.000000Z"
},
{
"id": 4,
"category_name": "Textile",
"category_synonym": null,
"created_at": "2020-05-31T21:29:30.000000Z",
"updated_at": "2020-05-31T21:29:30.000000Z"
}
]
I would like to put the category_name into a vue js dropdown contained into a foram.
How to make it simply ?
Vuetify select has item-text and item-value. You can use these props:
<v-select
label="Category"
:items="categories"
item-text="category_name"
item-value="id"
/>
You can try something like this:
<v-select v-model="currentCategory" :items="resultFromAPI" item-text="category_name" item-value="id" />
To fetch the data with Axios you can try something like this:
import axios from 'axios';
const ajax = axios.create({
baseURL: 'https://example.com/api',
headers: {
'Content-Type': 'application/json'
}
});
export default
{
data()
{
return {
categories: [],
currentCategory: null,
}
},
mounted()
{
this.fetchData();
},
methods:
{
fetchData()
{
ajax.get('/categories').then(response =>
{
this.currentCategory = null;
this.categories = response || [];
});
}
}
}

Assign array of JSON objects to array of interface Angular/Typescript

Currently, this works and doesn't give my error while running but my text editor is giving me an error that says property 'categories' does not exist on type 'CategoryInterface[]' (on the line where response.categories is assigned to variable) so I'm not sure if I'm doing things right.
public categories: CategoryInterface[];
.subscribe((response: CategoryInterface[]) => {
this.categories = response.categories;
console.log(this.categories);
});
My backend returns this:
{
"categories": [
{
"categoryId": 1,
"name": "Important",
"description": "This category is important.",
"order": 1,
"createdBy": null,
"createdAt": "2017-11-25 12:09:04",
"updatedBy": null,
"updatedAt": "2018-01-17 23:53:25",
"categoryBoards": [
{
"categoryBoardId": 1,
"categoryId": 1,
"name": "Announcements",
"description": null,
"order": 2,
"createdBy": null,
"createdAt": "2017-11-25 12:09:49",
"updatedBy": null,
"updatedAt": "2018-01-18 00:09:02"
},
{
"categoryBoardId": 23,
"categoryId": 1,
"name": "Rules",
"description": null,
"order": 1,
"createdBy": null,
"createdAt": "2018-01-18 00:08:57",
"updatedBy": null,
"updatedAt": "2018-01-19 00:05:51"
}
]
}
]
}
You are trying to cast your api response to an array of CategoryInterface which is not the case, you better use your subscribe method like this:
.subscribe((response: any) => {
this.categories = <CategoryInterface[]> response.categories;
console.log(this.categories);
});
It's the your api response categories which needs to be casted to CategoryInterface[]
Bonus: The angular style-guide notice that you need to declare classes instead of interfaces and you don't have to suffix the class name with Interface, so just name your CategoryInterface to Category.
You get the error because you declare response as a CategoryInterface[], but response.categories is actually the CategoryInterface[]. response is just a wrapper around the array. All the types are stripped out when the typescript is converted to javascript, which is why it works fine at runtime.

How do I expand nested relationships in REST API using Sails.js

I am a newbie to NodeJS and Sails.js.
I want create a REST API that allows me to expand a resource based on query parameter. For eg
HTTP GET /snippets
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "http://localhost:8000/snippets/1/",
"highlight": "htep://localhost:8000/snippets/1/highlight/",
"title": "test",
"code": "def test():\r\n pass",
"linenos": false,
"language": "Clipper",
"style": "autumn",
"owner": "http://localhost:8000/users/2/",
"extra": "http://localhost:8000/snippetextras/1/"
}
]}
HTTP GET /snippets?expand=owner
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"url": "http://localhost:8000/snippets/1/",
"highlight": "http://localhost:8000/snippets/1/highlight/",
"title": "test",
"code": "def test():\r\n pass",
"linenos": false,
"language": "Clipper",
"style": "autumn",
"owner": {
"url": "http://localhost:8000/users/2/",
"username": "test",
"email": "test#test.com"
},
"extra": "http://localhost:8000/snippetextras/1/"
}
]}
Wondering how can I do that in Sails.js or NodeJS?
You should use assocations.
Here is how you would create a one-to-many association between your User model and your Snippet model:
// User.js
module.exports = {
// ...
attributes: {
// ...
snippets: {
collection: 'Snippet',
via: 'owner'
}
}
};
// Snippet.js
module.exports = {
// ...
attributes: {
// ...
owner: {
model: 'User'
}
}
};
Then you can hit /snippets if you want a list of snippets, and hit /snippets?populate=[owner] if you need details about the owners of the snippets.

Categories