I'am a noob in react native and i'am writing my first app to read a response from an API. Till now i know how to make the call and get the response and parse the regular replies in an array in the state, but i'am not finding the right way to parse the json reply of this specific form. I tried saving it in an array but its not working.
{
"activities": [
{
"id": 19,
"files": [
{
"id": 63,
"created_at": "15/05/2020 15:09:34",
"updated_at": "15/05/2020 15:09:34",
"file": "/media/activities/newFile133.11531268506258.jpg",
"is_default": false,
"activity": 19
},
{
"id": 65,
"created_at": "15/05/2020 15:10:15",
"updated_at": "15/05/2020 15:10:15",
"file": "/media/activities/newFile203.0997630588359.jpg",
"is_default": false,
"activity": 19
},
{
"id": 64,
"created_at": "15/05/2020 15:09:53",
"updated_at": "15/05/2020 15:10:27",
"file": "/media/activities/newFile193.8056151444231.jpg",
"is_default": true,
"activity": 19
},
{
"id": 62,
"created_at": "15/05/2020 15:08:56",
"updated_at": "15/05/2020 15:10:27",
"file": "/media/activities/newFile39.839136995440484.jpg",
"is_default": false,
"activity": 19
}
],
"created_at": "15/05/2020 14:52:54",
"updated_at": "15/05/2020 14:58:01",
"title": "Camping",
"description": "Camp Al Wilayah",
"category": 10
},
{
"id": 21,
"files": [
{
"id": 66,
"created_at": "15/05/2020 15:16:02",
"updated_at": "15/05/2020 15:16:02",
"file": "/media/activities/newFile46.35084778104737.jpg",
"is_default": true,
"activity": 21
},
{
"id": 67,
"created_at": "15/05/2020 15:16:33",
"updated_at": "15/05/2020 15:16:33",
"file": "/media/activities/newFile49.28140513312763.jpg",
"is_default": false,
"activity": 21
}
],
"created_at": "15/05/2020 15:11:22",
"updated_at": "15/05/2020 15:11:22",
"title": "Aashoura",
"description": "Majlis Aazaa",
"category": 12
},
{
"id": 18,
"files": [
{
"id": 68,
"created_at": "15/05/2020 15:21:18",
"updated_at": "15/05/2020 15:21:18",
"file": "/media/activities/newFile71.35101359514769.jpg",
"is_default": true,
"activity": 18
},
{
"id": 69,
"created_at": "15/05/2020 15:22:42",
"updated_at": "15/05/2020 15:22:42",
"file": "/media/activities/newFile107.17719628795922.jpg",
"is_default": false,
"activity": 18
}
],
"created_at": "15/05/2020 14:52:11",
"updated_at": "15/05/2020 15:17:34",
"title": "Takliff",
"description": "Taklif ceremony",
"category": 7
},
{
"id": 22,
"files": [
{
"id": 70,
"created_at": "15/05/2020 15:42:18",
"updated_at": "15/05/2020 15:43:03",
"file": "/media/activities/97026390_682458148963323_2038839267676913664_n.mp4",
"is_default": true,
"activity": 22
}
],
"created_at": "15/05/2020 15:24:46",
"updated_at": "15/05/2020 15:24:46",
"title": "Laylat Qader",
"description": "Event of Laylat al Qader",
"category": 6
},
{
"id": 23,
"files": [
{
"id": 73,
"created_at": "15/05/2020 17:42:43",
"updated_at": "15/05/2020 17:42:43",
"file": "/media/activities/newFile47.470692661344614.jpg",
"is_default": false,
"activity": 23
},
{
"id": 74,
"created_at": "15/05/2020 18:30:05",
"updated_at": "26/05/2020 21:34:09",
"file": "/media/activities/newFile28.504968134645907.jpg",
"is_default": false,
"activity": 23
},
{
"id": 72,
"created_at": "15/05/2020 15:51:29",
"updated_at": "15/07/2020 07:49:27",
"file": "/media/activities/newFile82.57124842095388.jpg",
"is_default": false,
"activity": 23
},
{
"id": 71,
"created_at": "15/05/2020 15:50:59",
"updated_at": "15/07/2020 07:50:09",
"file": "/media/activities/newFile3.0461490605067763.jpg",
"is_default": true,
"activity": 23
}
],
"created_at": "15/05/2020 15:50:36",
"updated_at": "15/07/2020 07:46:38",
"title": "Zayyana Al Dar",
"description": "Young generation posts",
"category": 11
}
],
"total": 5
}
Firstly, entire response is inside object bracket {}.
So, response.activities will give array of a activities.
Then use it like var x = response.activities
var first = x[0]
var second = x[1]
and so on .
It was my bad for checking the "activities" array in the state by "console.log(this.state.activities)" in the ".then" that is right after the setState function. i thought the code won't move to the second ".then" unless done with the first, so it was getting parsed in the way rock stated but printed in the console before that.
Related
I got a collection but I want to sort that collection. If the two application's cgpa is equal then sort the list collection according to the annual_salary where lower will up at list. Default the collection sort with the cgpa. below is my server response.
Thanks in advance
"applications": [
{
"id": 1,
"name": "Dr. W Khan",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z",
"education": [
{
"id": 1,
"application_id": 1,
"name": "HSC",
"cgpa": 400,
"created_at": "2022-11-07T19:16:01.000000Z",
"updated_at": "2022-11-07T19:16:01.000000Z"
}
]
},
{
"id": 2,
"name": "Dr. M Khan",
"annual_salary": 7000,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z",
"education": [
{
"id": 2,
"application_id": 2,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:14.000000Z",
"updated_at": "2022-11-07T19:16:14.000000Z"
}
]
},
{
"id": 3,
"name": "Dr.",
"annual_salary": 5000,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z",
"education": [
{
"id": 3,
"application_id": 3,
"name": "HSC",
"cgpa": 350,
"created_at": "2022-11-07T19:16:28.000000Z",
"updated_at": "2022-11-07T19:16:28.000000Z"
}
]
}
]
This is the query for me.
$application = Application::with(
[
'education' => function ($query) {
$query->orderBy('cgpa', 'desc');
},
]
)
->orderBy('annual_salary', 'asc')
->get();
But ordering the list followed by a second orderBy.
In my Flutter project i would like to get datas from an API.
I used QuickType to generate my classes to parse my Json.
This error is always occured:
_TypeError (type 'List' is not a subtype of type 'String')
This my API response:
[
{
"id": 1,
"label": "Animals",
"created_at": "2022-05-25T13:36:42.517Z",
"updated_at": "2022-05-25T13:36:42.517Z",
"sub_categories": [
{
"id": 2,
"label": "Ant",
"category": 1,
"published_at": "2022-05-25T13:40:48.172Z",
"created_at": "2022-05-25T13:40:48.174Z",
"updated_at": "2022-05-25T16:29:58.047Z"
},
{
"id": 3,
"label": "Cats",
"category": 1,
"published_at": "2022-05-25T13:42:07.022Z",
"created_at": "2022-05-25T13:42:07.023Z",
"updated_at": "2022-05-25T16:30:08.576Z"
},
{
"id": 4,
"label": "Dogs",
"category": 1,
"published_at": "2022-05-25T13:42:12.270Z",
"created_at": "2022-05-25T13:42:12.271Z",
"updated_at": "2022-05-25T16:30:14.262Z"
}
]
},
{
"id": 2,
"label": "Art",
"created_at": "2022-05-25T13:36:45.994Z",
"updated_at": "2022-05-25T13:36:45.994Z",
"sub_categories": [
{
"id": 7,
"label": "Paint",
"category": 2,
"published_at": "2022-05-28T08:01:46.941Z",
"created_at": "2022-05-28T08:01:46.943Z",
"updated_at": "2022-05-28T08:01:46.948Z"
}
]
},
{
"id": 3,
"label": "Astrology",
"created_at": "2022-05-25T13:36:49.498Z",
"updated_at": "2022-05-25T13:36:49.498Z",
"sub_categories": [
{
"id": 8,
"label": "Taurus",
"category": 3,
"published_at": "2022-05-28T08:02:07.520Z",
"created_at": "2022-05-28T08:02:07.521Z",
"updated_at": "2022-05-28T08:02:07.526Z"
}
]
},
{
"id": 4,
"label": "Astronomy",
"created_at": "2022-05-25T13:36:54.035Z",
"updated_at": "2022-05-25T13:36:54.035Z",
"sub_categories": [
{
"id": 9,
"label": "Hubble",
"category": 4,
"published_at": "2022-05-28T08:02:14.747Z",
"created_at": "2022-05-28T08:02:14.748Z",
"updated_at": "2022-05-28T08:02:14.753Z"
}
]
},
{
"id": 5,
"label": "Cook",
"created_at": "2022-05-25T13:37:34.930Z",
"updated_at": "2022-05-25T13:37:34.930Z",
"sub_categories": [
{
"id": 5,
"label": "Plancha",
"category": 5,
"published_at": "2022-05-25T13:42:26.369Z",
"created_at": "2022-05-25T13:42:26.370Z",
"updated_at": "2022-05-25T16:30:23.512Z"
},
{
"id": 6,
"label": "Bakery",
"category": 5,
"published_at": "2022-05-25T16:31:49.887Z",
"created_at": "2022-05-25T16:31:49.890Z",
"updated_at": "2022-05-25T16:31:49.900Z"
}
]
},
{
"id": 6,
"label": "Crypto Currencies",
"created_at": "2022-05-25T13:37:43.113Z",
"updated_at": "2022-05-25T13:37:43.113Z",
"sub_categories": [
{
"id": 10,
"label": "Bitcoin",
"category": 6,
"published_at": "2022-05-28T08:02:52.814Z",
"created_at": "2022-05-28T08:02:52.815Z",
"updated_at": "2022-05-28T08:02:52.821Z"
}
]
},
{
"id": 7,
"label": "DIY",
"created_at": "2022-05-25T13:37:48.652Z",
"updated_at": "2022-05-25T13:37:48.652Z",
"sub_categories": [
{
"id": 11,
"label": "Tools",
"category": 7,
"published_at": "2022-05-28T08:03:05.030Z",
"created_at": "2022-05-28T08:03:05.031Z",
"updated_at": "2022-05-28T08:03:05.038Z"
}
]
},
{
"id": 8,
"label": "Ecology",
"created_at": "2022-05-25T13:37:53.776Z",
"updated_at": "2022-05-25T13:37:53.776Z",
"sub_categories": [
{
"id": 12,
"label": "Planet",
"category": 8,
"published_at": "2022-05-28T08:03:19.915Z",
"created_at": "2022-05-28T08:03:19.916Z",
"updated_at": "2022-05-28T08:03:19.922Z"
}
]
},
{
"id": 9,
"label": "Economy",
"created_at": "2022-05-25T13:37:59.384Z",
"updated_at": "2022-05-25T13:37:59.384Z",
"sub_categories": [
{
"id": 13,
"label": "Wall Street",
"category": 9,
"published_at": "2022-05-28T08:03:41.942Z",
"created_at": "2022-05-28T08:03:41.943Z",
"updated_at": "2022-05-28T08:03:41.948Z"
}
]
},
{
"id": 10,
"label": "Literature",
"created_at": "2022-05-25T13:38:07.354Z",
"updated_at": "2022-05-25T13:38:07.354Z",
"sub_categories": [
{
"id": 14,
"label": "Zola",
"category": 10,
"published_at": "2022-05-28T08:03:59.314Z",
"created_at": "2022-05-28T08:03:59.316Z",
"updated_at": "2022-05-28T08:03:59.322Z"
}
]
},
{
"id": 11,
"label": "Mode",
"created_at": "2022-05-25T13:38:32.915Z",
"updated_at": "2022-05-25T13:38:32.915Z",
"sub_categories": [
{
"id": 15,
"label": "Squirt",
"category": 11,
"published_at": "2022-05-28T08:04:10.245Z",
"created_at": "2022-05-28T08:04:10.246Z",
"updated_at": "2022-05-28T08:08:02.312Z"
}
]
},
{
"id": 12,
"label": "Movies",
"created_at": "2022-05-25T13:38:36.502Z",
"updated_at": "2022-05-25T13:38:36.502Z",
"sub_categories": [
{
"id": 16,
"label": "Tarantino",
"category": 12,
"published_at": "2022-05-28T08:04:48.519Z",
"created_at": "2022-05-28T08:04:48.520Z",
"updated_at": "2022-05-28T08:04:48.526Z"
}
]
},
{
"id": 13,
"label": "Music",
"created_at": "2022-05-25T13:38:41.227Z",
"updated_at": "2022-05-25T13:38:41.227Z",
"sub_categories": [
{
"id": 17,
"label": "Rock",
"category": 13,
"published_at": "2022-05-28T08:05:20.575Z",
"created_at": "2022-05-28T08:05:20.576Z",
"updated_at": "2022-05-28T08:05:20.580Z"
}
]
},
{
"id": 14,
"label": "Nature",
"created_at": "2022-05-25T13:38:46.772Z",
"updated_at": "2022-05-25T13:38:46.772Z",
"sub_categories": [
{
"id": 18,
"label": "Forest",
"category": 14,
"published_at": "2022-05-28T08:05:32.566Z",
"created_at": "2022-05-28T08:05:32.567Z",
"updated_at": "2022-05-28T08:05:32.572Z"
}
]
},
{
"id": 15,
"label": "Politic",
"created_at": "2022-05-25T13:38:52.016Z",
"updated_at": "2022-05-25T13:38:52.016Z",
"sub_categories": [
{
"id": 19,
"label": "Vote",
"category": 15,
"published_at": "2022-05-28T08:05:38.045Z",
"created_at": "2022-05-28T08:05:38.046Z",
"updated_at": "2022-05-28T08:05:38.052Z"
}
]
},
{
"id": 16,
"label": "Sciences",
"created_at": "2022-05-25T13:38:58.047Z",
"updated_at": "2022-05-25T13:38:58.047Z",
"sub_categories": [
{
"id": 20,
"label": "Chemistry",
"category": 16,
"published_at": "2022-05-28T08:05:51.520Z",
"created_at": "2022-05-28T08:05:51.521Z",
"updated_at": "2022-05-28T08:05:51.528Z"
},
{
"id": 21,
"label": "Chemistery",
"category": 16,
"published_at": "2022-05-28T08:05:54.625Z",
"created_at": "2022-05-28T08:05:54.627Z",
"updated_at": "2022-05-28T08:05:54.631Z"
}
]
},
{
"id": 17,
"label": "Series",
"created_at": "2022-05-25T13:39:02.864Z",
"updated_at": "2022-05-25T13:39:02.864Z",
"sub_categories": [
{
"id": 22,
"label": "GOT",
"category": 17,
"published_at": "2022-05-28T08:06:06.350Z",
"created_at": "2022-05-28T08:06:06.351Z",
"updated_at": "2022-05-28T08:06:06.355Z"
}
]
},
{
"id": 18,
"label": "Sexuality",
"created_at": "2022-05-25T13:39:10.901Z",
"updated_at": "2022-05-25T13:39:10.901Z",
"sub_categories": [
{
"id": 23,
"label": "Couple",
"category": 18,
"published_at": "2022-05-28T08:06:33.963Z",
"created_at": "2022-05-28T08:06:33.964Z",
"updated_at": "2022-05-28T08:06:33.968Z"
}
]
},
{
"id": 19,
"label": "Social Life",
"created_at": "2022-05-25T13:39:16.760Z",
"updated_at": "2022-05-25T13:39:16.760Z",
"sub_categories": [
{
"id": 24,
"label": "Interractions",
"category": 19,
"published_at": "2022-05-28T08:06:55.099Z",
"created_at": "2022-05-28T08:06:55.099Z",
"updated_at": "2022-05-28T08:06:55.104Z"
}
]
},
{
"id": 20,
"label": "Sport",
"created_at": "2022-05-25T13:39:21.296Z",
"updated_at": "2022-05-25T13:39:21.296Z",
"sub_categories": [
{
"id": 25,
"label": "Football",
"category": 20,
"published_at": "2022-05-28T08:07:13.972Z",
"created_at": "2022-05-28T08:07:13.973Z",
"updated_at": "2022-05-28T08:07:13.979Z"
}
]
},
{
"id": 21,
"label": "Theater",
"created_at": "2022-05-25T13:39:26.063Z",
"updated_at": "2022-05-25T13:39:26.063Z",
"sub_categories": [
{
"id": 26,
"label": "Molière",
"category": 21,
"published_at": "2022-05-28T08:07:22.217Z",
"created_at": "2022-05-28T08:07:22.219Z",
"updated_at": "2022-05-28T08:07:22.224Z"
}
]
},
{
"id": 22,
"label": "Vehicules",
"created_at": "2022-05-25T13:39:30.859Z",
"updated_at": "2022-05-25T13:39:30.859Z",
"sub_categories": [
{
"id": 27,
"label": "Audi",
"category": 22,
"published_at": "2022-05-28T08:07:30.514Z",
"created_at": "2022-05-28T08:07:30.515Z",
"updated_at": "2022-05-28T08:07:30.522Z"
}
]
},
{
"id": 23,
"label": "Video Games",
"created_at": "2022-05-25T13:39:36.926Z",
"updated_at": "2022-05-25T13:39:36.926Z",
"sub_categories": [
{
"id": 28,
"label": "Elden Ring",
"category": 23,
"published_at": "2022-05-28T08:07:38.335Z",
"created_at": "2022-05-28T08:07:38.339Z",
"updated_at": "2022-05-28T08:07:38.343Z"
}
]
}
]
My classes generated by QuickType:
class Category {
Category({
required this.id,
required this.label,
required this.createdAt,
required this.updatedAt,
required this.subCategories,
});
int id;
String label;
DateTime createdAt;
DateTime updatedAt;
List<SubCategory> subCategories;
factory Category.fromRawJson(String str) =>
Category.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory Category.fromJson(Map<String, dynamic> json) => Category(
id: json["id"],
label: json["label"],
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
subCategories: List<SubCategory>.from(
json["sub_categories"].map((x) => SubCategory.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"id": id,
"label": label,
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
"sub_categories":
List<dynamic>.from(subCategories.map((x) => x.toJson())),
};
}
class SubCategory {
SubCategory({
required this.id,
required this.label,
required this.category,
required this.publishedAt,
required this.createdAt,
required this.updatedAt,
});
int id;
String label;
int category;
DateTime publishedAt;
DateTime createdAt;
DateTime updatedAt;
factory SubCategory.fromRawJson(String str) =>
SubCategory.fromJson(json.decode(str));
String toRawJson() => json.encode(toJson());
factory SubCategory.fromJson(Map<String, dynamic> json) => SubCategory(
id: json["id"],
label: json["label"],
category: json["category"],
publishedAt: DateTime.parse(json["published_at"]),
createdAt: DateTime.parse(json["created_at"]),
updatedAt: DateTime.parse(json["updated_at"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"label": label,
"category": category,
"published_at": publishedAt.toIso8601String(),
"created_at": createdAt.toIso8601String(),
"updated_at": updatedAt.toIso8601String(),
};
}
And this is my code:
List<Category> categoryFromJson(String str) =>
List<Category>.from(json.decode(str).map((x) => Category.fromJson(x)));
String categoryToJson(List<Category> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
Future<List<Category>> getCategories() async {
var response =
await http.get(Uri.parse("http://192.168.0.10:1337/categories/"));
if (response.statusCode == 200) {}
var decodedData = jsonDecode(response.body);
final category = categoryFromJson(decodedData);
print(category);
return category;
}
Thank you for your awnsers :)
API providing list of data, try using
Future<List<Category>?> loadData() async {
//use http insted of `rootBundle`
final response = await rootBundle.loadString("assets/j.json");
var decodedData = jsonDecode(response) as List;
final items = decodedData.map((e) => Category.fromJson(e)).toList();
return items;
}
In my case the json will be different every time and i have to make widget like "inputtype": "dropdown", "inputtype": "radiobutton" but if i craete model it don't go as i wants it to.
{
"fields": [
{
"id": 31,
"name": "make",
"isrequired": "required",
"valuetype": "text",
"priority": 1,
"inputtype": "dropdown",
"max_min": [],
"rangeable": "false",
"choices": [
{
"id": 46,
"name": "Samsung",
"categoryextrafield_id": 31,
"created_at": "2021-12-29T01:30:47.000000Z",
"updated_at": "2021-12-29T01:30:47.000000Z",
"priority": 10
},
{
"id": 47,
"name": "Dell",
"categoryextrafield_id": 31,
"created_at": "2021-12-29T01:30:52.000000Z",
"updated_at": "2021-12-29T01:30:52.000000Z",
"priority": 20
},
{
"id": 48,
"name": "IBM",
"categoryextrafield_id": 31,
"created_at": "2021-12-29T01:31:09.000000Z",
"updated_at": "2021-12-29T01:31:09.000000Z",
"priority": 30
},
{
"id": 49,
"name": "Acer",
"categoryextrafield_id": 31,
"created_at": "2021-12-29T01:31:24.000000Z",
"updated_at": "2021-12-29T01:31:24.000000Z",
"priority": 40
}
],
"available": []
},
{
"id": 32,
"name": "model",
"isrequired": "required",
"valuetype": "text",
"priority": 2,
"inputtype": "textfield",
"max_min": [],
"rangeable": "false",
"choices": [],
"available": [
{
"model": "a51"
},
{
"model": "y9s"
},
{
"model": "a31"
},
{
"model": "yS10"
},
{
"model": "Y10S"
},
{
"model": "A551"
},
{
"model": "node8"
},
{
"model": "s9"
},
{
"model": null
},
{
"model": "2021"
},
{
"model": "2020"
},
{
"model": "2010"
},
{
"model": "Civic"
},
{
"model": "2019"
},
{
"model": "Daewooy9"
},
{
"model": "corei5"
},
{
"model": "corei9"
},
{
"model": "corei3"
},
{
"model": "corei11"
}
]
},
{
"id": 29,
"name": "features",
"isrequired": "required",
"valuetype": "text",
"priority": 3,
"inputtype": "checkbox",
"max_min": [],
"rangeable": "false",
"choices": [
{
"id": 41,
"name": "Bluetooth",
"categoryextrafield_id": 29,
"created_at": "2021-12-29T01:19:00.000000Z",
"updated_at": "2021-12-29T01:19:00.000000Z",
"priority": 1
},
{
"id": 42,
"name": "Fingerprint",
"categoryextrafield_id": 29,
"created_at": "2021-12-29T01:19:10.000000Z",
"updated_at": "2021-12-29T01:19:10.000000Z",
"priority": 10
},
{
"id": 43,
"name": "LedDisplay",
"categoryextrafield_id": 29,
"created_at": "2021-12-29T01:19:35.000000Z",
"updated_at": "2021-12-29T01:19:35.000000Z",
"priority": 15
}
],
"available": []
},
{
"id": 30,
"name": "condition",
"isrequired": "required",
"valuetype": "text",
"priority": 4,
"inputtype": "radiobutton",
"max_min": [],
"rangeable": "false",
"choices": [
{
"id": 44,
"name": "Used",
"categoryextrafield_id": 30,
"created_at": "2021-12-29T01:20:31.000000Z",
"updated_at": "2021-12-29T01:20:31.000000Z",
"priority": 10
},
{
"id": 45,
"name": "New",
"categoryextrafield_id": 30,
"created_at": "2021-12-29T01:20:38.000000Z",
"updated_at": "2021-12-29T01:20:38.000000Z",
"priority": 20
}
],
"available": []
}
]
}
I am trying to get the image URL from a JSON which I get from a call to my strapi content. It is for an events website. Here is the code. When I console.log the image url, i get 'undefined'. However, all other properties of event show up no problem.
created() {
axios.get('http://localhost:1338/events').then(res => {
this.events = res.data.sort((a, b) => b.date < a.date ? 1: -1);
console.log(this.events[0].image.url)
})
.catch(err => console.log(err))
}
Console: undefined
Here is the JSON:
{
"id": 1,
"title": "Aphex Twin Live Set",
"description": "Risus viverra adipiscing at in tellus integer feugiat scelerisque varius.",
"date": "2020-12-23T16:00:00.000Z",
"price": 10,
"published_at": "2020-12-19T17:25:44.340Z",
"created_at": "2020-12-19T17:25:41.833Z",
"updated_at": "2020-12-19T21:42:15.696Z",
"image": [
{
"id": 1,
"name": "aphex.jpeg",
"alternativeText": "",
"caption": "",
"width": 1200,
"height": 630,
"formats": {
"thumbnail": {
"name": "thumbnail_aphex.jpeg",
"hash": "thumbnail_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 245,
"height": 129,
"size": 4.12,
"path": null,
"url": "/uploads/thumbnail_aphex_11b34d4058.jpeg"
},
"large": {
"name": "large_aphex.jpeg",
"hash": "large_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 1000,
"height": 525,
"size": 28.49,
"path": null,
"url": "/uploads/large_aphex_11b34d4058.jpeg"
},
"medium": {
"name": "medium_aphex.jpeg",
"hash": "medium_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 750,
"height": 394,
"size": 18.95,
"path": null,
"url": "/uploads/medium_aphex_11b34d4058.jpeg"
},
"small": {
"name": "small_aphex.jpeg",
"hash": "small_aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 500,
"height": 263,
"size": 10.67,
"path": null,
"url": "/uploads/small_aphex_11b34d4058.jpeg"
}
},
"hash": "aphex_11b34d4058",
"ext": ".jpeg",
"mime": "image/jpeg",
"size": 37.07,
"url": "/uploads/aphex_11b34d4058.jpeg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2020-12-19T17:25:35.172Z",
"updated_at": "2020-12-19T17:25:35.183Z"
}
],
"categories": [
{
"id": 1,
"name": "Music",
"published_at": "2020-12-19T21:18:16.946Z",
"created_at": "2020-12-19T21:18:13.393Z",
"updated_at": "2020-12-19T21:18:16.961Z"
}
],
"artists": [
{
"id": 1,
"name": "Aphex Twin",
"bio": "Richard James is a pretty old guy by now but he was banging in the techno/ambient electronic scene in the late 80s and 90s. He's from Cornwall so must've been pretty bored on most days, which lead him to hack at computers and electronic sound generators. The rest is history.",
"published_at": "2020-12-19T21:42:33.225Z",
"created_at": "2020-12-19T21:42:03.445Z",
"updated_at": "2020-12-19T21:42:33.251Z",
"artist_image": []
}
]
}
Again -- all fields show if I console.log, but not image.url
Got it -- the image field is an array because I allowed multiple media on Strapi. Had to do event.image[0].url
i have the following Template model and TestCategory hasMany Test:
class Template extends Model
{
protected $table = 'test_templates';
protected $fillable = [
'customers_id',
'tests_categories_id',
'tests_id'
];
public function customers(){
return $this->belongsTo(Customer::class, 'customers_id');
}
public function testCategories(){
return $this->belongsTo(TestCategory::class, 'tests_categories_id');
}
public function tests(){
return $this->belongsTo(Test::class, 'tests_id');
}
}
And I have the following index method defined in TemplateController
public function index($customerId)
{
$templates = Template::with( 'customers','testCategories','tests')
->where('customers_id', $customerId)->get();
$templates = $templates->groupBy('tests_categories_id');
$templates = json_decode($templates, true);
$templates = array_values($templates);
return response()->json(['Status' => True, 'template' => $templates]);
}
I got the following json output:
{
"Status": true,
"template": [
[
{
"id": 1,
"customers_id": 1,
"tests_categories_id": 1,
"tests_id": 1,
"created_at": "2018-09-10 11:03:44",
"updated_at": "2018-09-10 11:03:44",
"customers": {
"id": 1,
"name": "Queen PVT.Ltd",
"address": "gotham",
"contact_number": "9842********",
"created_at": "2018-09-10 11:03:43",
"updated_at": "2018-09-10 11:03:43"
},
"test_categories": {
"id": 1,
"name": "General Tests",
"created_at": null,
"updated_at": null
},
"tests": {
"id": 1,
"tests_category_id": 1,
"name": "Lamination",
"created_at": null,
"updated_at": null
}
},
{
"id": 2,
"customers_id": 1,
"tests_categories_id": 1,
"tests_id": 2,
"created_at": "2018-09-10 11:03:44",
"updated_at": "2018-09-10 11:03:44",
"customers": {
"id": 1,
"name": "Queen PVT.Ltd",
"address": "gotham",
"contact_number": "984*******",
"created_at": "2018-09-10 11:03:43",
"updated_at": "2018-09-10 11:03:43"
},
"test_categories": {
"id": 1,
"name": "General Tests",
"created_at": null,
"updated_at": null
},
"tests": {
"id": 2,
"tests_category_id": 1,
"name": "Paper Type",
"created_at": null,
"updated_at": null
}
}
],
[
{
"id": 7,
"customers_id": 1,
"tests_categories_id": 2,
"tests_id": 8,
"created_at": "2018-09-10 11:03:44",
"updated_at": "2018-09-10 11:03:44",
"customers": {
"id": 1,
"name": "Queen PVT.Ltd",
"address": "gotham",
"contact_number": "984******",
"created_at": "2018-09-10 11:03:43",
"updated_at": "2018-09-10 11:03:43"
},
"test_categories": {
"id": 2,
"name": "Scratch Test",
"created_at": null,
"updated_at": null
},
"tests": {
"id": 8,
"tests_category_id": 2,
"name": "HRN Visibility",
"created_at": null,
"updated_at": null
}
}
]
]
}
I want to collect all the tests as per the test_categories without reprinting customers and test_categories as following:
{
"Status": true,
"template": [
[
{
"id": 1,
"customers_id": 1,
"tests_categories_id": 1,
"tests_id": 1,
"created_at": "2018-09-10 11:03:44",
"updated_at": "2018-09-10 11:03:44",
"customers": {
"id": 1,
"name": "Queen PVT.Ltd",
"address": "gotham",
"contact_number": "984*****",
"created_at": "2018-09-10 11:03:43",
"updated_at": "2018-09-10 11:03:43"
},
"test_categories": {
"id": 1,
"name": "General Tests",
"created_at": null,
"updated_at": null
},
"tests": {
{
"id": 1,
"tests_category_id": 1,
"name": "Lamination",
"created_at": null,
"updated_at": null
},
{
"id": 2,
"tests_category_id": 1,
"name": "Paper Type",
"created_at": null,
"updated_at": null
}
}
}
],
[
{
"id": 7,
"customers_id": 1,
"tests_categories_id": 2,
"tests_id": 8,
"created_at": "2018-09-10 11:03:44",
"updated_at": "2018-09-10 11:03:44",
"customers": {
"id": 1,
"name": "Queen PVT.Ltd",
"address": "gotham",
"contact_number": "984265*****",
"created_at": "2018-09-10 11:03:43",
"updated_at": "2018-09-10 11:03:43"
},
"test_categories": {
"id": 2,
"name": "Scratch Test",
"created_at": null,
"updated_at": null
},
"tests": {
{
"id": 8,
"tests_category_id": 2,
"name": "HRN Visibility",
"created_at": null,
"updated_at": null
}
}
}
]
]
}
If I understand the problem correctly the tests are being separated into different templates when you are expecting some of them to be related to the same template.
This is because your Template class is storing the test_id that it belongs to and it can only store 1 test per Template. So when you are calling Template::with('tests') it can only return one Test::class.
Because you expect to see that many Tests belongTo one Template, and when you look at the relationship from the Template to Test, you expect that a Template has many Tests. Therefore, your Template class should implement the hasMany relationship like so:
class Template extends Model
{
protected $fillable = [
'customers_id',
'tests_categories_id' // notice the removal of the test_id which should also be removed from the test_templates migration
];
...
public function tests(){
return $this->hasMany(Test::class); //change belongsTo to hasMany
}
...
}
Instead of storing the test_id on the Template class you should be storing the template_id on your Test class and look something like so:
class Test extends Model
{
protected $fillable = [
...
'test_template_id' // This should be added to $fillable and the tests migration
...
];
...
public function template(){
return $this->belongsTo(Template::class, test_template_id);
}
...
}
Now when you call Template::with('tests') it can return many Test::class and should match your expected output.