How to access forgin key value in react from django api - reactjs

I have django api in which i have post model which is linked to comments and categories table by forgin key now i am feching data for post detail and when i try to access category of that post it return s id and i want to access name of category this is my post list view
{
"id": 4,
"title": "BLOG PAGE",
"body": "testing",
"owner": "ankit",
"comments": [],
"categories": [
2
],
"created_at": "2021-05-07T17:22:32.989706Z"
},
{
"id": 5,
"title": "Test Post",
"body": "This is a test Post",
"owner": "ankit",
"comments": [],
"categories": [
2
],
and this is my categories
[
{
"id": 2,
"name": "Python",
"owner": "ankit",
"posts": [
4,
5,
6,
8
]
}
]
and this is my post detail component
export class PostDetail extends React.Component {
constructor(props) {
super(props);
const ID = this.props.match.params.id
this.state = {
data: [],
loaded: false,
placeholder: "Loading"
};
}
formatDate(dateString){
const options = { year: "numeric", month: "long", day: "numeric" }
return new Date(dateString).toLocaleDateString(undefined, options)
}
componentDidMount() {
fetch(`${Url}posts/${this.props.match.params.id}`)
.then(response => {
if (response.status > 400) {
return this.setState(() => {
return { placeholder: "Something went wrong!" };
});
}
return response.json();
})
.then(data => {
this.setState(() => {
return {
data,
loaded: true
};
});
});
}
render(){
return(
<>
<h1 className="main-title">{this.state.data.title}</h1>
<div className="container">
<div className="box1">
<h2>Categories</h2>
<div className="categories">{this.state.data.categories}</div>
</div>
</>
);
}
}
and i am getting output as 2 when i try to get data like mention above
i thought i can access it by putting . in front of categories eg. categories.name but it returns TypeError error
TypeError: Cannot read property 'name' of undefined
this are my serializers
class CategorySerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
posts = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Category
fields = ['id', 'name', 'owner', 'posts']
class PostSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Post
fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']

i try to access category of that post it return s id and i want to access name of category this is my post list view
1. For getting only the name of the category.
You can use the SlugRelatedField.
Modify your PostSerializer like so:
class PostSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
categories = serializers.SlugRelatedField(many=True, read_only=True, slug_field='name')
class Meta:
model = Post
fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']
Example JSON response:
{
"id": 4,
"title": "BLOG PAGE",
"body": "testing",
"owner": "ankit",
"comments": [],
"categories": [
"Python"
],
"created_at": "2021-05-07T17:22:32.989706Z"
},
2. To nest full Category objects
class PostSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username')
comments = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
categories = CategorySerializer(many=True)
class Meta:
model = Post
fields = ['id', 'title', 'body', 'owner', 'comments', 'categories','created_at']
Example JSON response:
{
"id":4,
"title":"BLOG PAGE",
"body":"testing",
"owner":"ankit",
"comments":[],
"categories":[
{
"id":2,
"name":"Python",
"owner":"ankit",
"posts":[
4,
5,
6,
8
]
}
],
"created_at":"2021-05-07T17:22:32.989706Z"
}

Related

reactjs & woocommerce rest api - add item to cart with selected options' value

I am working on a react frontend for a woocommerce shop and I am currently trying to add an item to the cart with the selected option values ie size and color.
My current api call -
const AddToCart = async (id) => {
let config = {
method: "post",
url: "/wp-json/wc/store/v1/cart/add-item",
data: {
id : id,
quantity: 1,
attributes: [
{
color: color
},
{
size: size
}]
}
}
const resp = await axios(config).then((response) => {
console.log(response.data)
})
.catch((error) => {
console.log(error.response.data);
});
}
In the docs it says -
Chosen attributes (for variations) containing an array of objects with
keys attribute and value
However what I've tried is giving me this error -
code: "woocommerce_rest_variation_id_from_variation_data"
data: {status: 400}
message: "No matching variation found."
Example json response for single product -
{
"id": 933,
.......
"attributes": [
{
"id": 1,
"name": "Size",
"position": 0,
"visible": false,
"variation": true,
"options": [
"2XL",
"3XL",
"4XL",
"5XL",
"L",
"M",
"S",
"XL",
"XS"
]
}
],
"default_attributes": [],
"variations": [
936,
937,
938,
939,
940,
941,
942,
943,
944
],
......
You have to pass the data like this:
data: {
id: id,
quantity: 1,
variation: [
{
attribute: "color"
value: color,
},
{
attribute: "size"
value: size,
}
]
}
As per documentation, variation accepts the array of objects and objects should have keys attribute and value.
what's wrong with this
[{ attribute: 'color', value : selectedColor },{ attribute : 'size', value : selected }]

Firestore - Combine documents from two different collection - React Typescript

I have created three collections because I want to be able to do filter search by tasks or users etc
My Firebase collection looks like this:
Collection 1 - (Users)
- username
- name
Collection 2 - (Tasks)
- taskname
- points
Collection 3 - (taskData)
- userId (id from users collection)
- taskId (id from task collection)
- timestamp
React Typescript - Fetch collection data
interface UserTask {
id: String;
taskId: String;
userId: String;
date: Date;
}
const [userTasks, setUserTasks] = useState<UserTask[]>([]);
const getTaskData = () => {
const taskRef = firestore.collection('taskData');
taskRef.get().then((snapshot) => {
const taskData = snapshot.docs.map((doc) => ({
id: doc.id,
...doc.data()
}))
console.log(taskData)
})
}
I am able to get the TaskData which has userId and TaskId but have not been able to "join" the tables and get Users.name and Tasks.taskname.I want to get a output like below, How do I do that?
{
"taskName1": [
{
"name": "John",
"date": "12.01.2002"
},
{
"name": "Maya",
"date": "15.01.2002"
},
{
"name": "Hanna",
"date": "13.01.2003"
}
],
"taskName2": [
{
"name": "Maya",
"date": "20.04.2003"
},
{
"name": "Maya",
"date": "17.06.2003"
}
],
"taskName3": [
{
"name": "John",
"date": "21.05.2003"
}
]
}

How to create nested array in realm without key(React Native)

{
"a": [
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
],
[
{
"_id": "57e55b64016c3551c025abc1",
"title": "Main Campus"
},
{
"_id": "5810e2e27064497f74ad4874",
"title": "Ahm Campus"
},
{
"_id": "5d5d2633a1d0680620ac3cce",
"title": "Baroda"
},
{
"_id": "5d5d3af3a1d0680620ac3ef8",
"title": "India"
}
]
]
}
How to create the schema in the realm(React native) for this type of JSON object. I tried all possible ways but did not found any specific solution. Basically, it is a nested array where the second array does not have any specific key(I tried with key it works fine but I want to do it without adding key).
You can use something like:
const ParentSchema = {
name: "parent",
properties: {
key: "string",
values: "Value[]"
}
};
const ValueSchema = {
name: "Value",
embedded: true,
properties: {
_id: "string",
title: "string"
}
};
You can insert objects like:
realm.write(() => {
realm.create("Parent", { key: "a", values: [
{ _id: "57e55b64016c3551c025abc1", title: "Main Campus" },
{ _id: "5810e2e27064497f74ad4874", title: "Ahm Campus" }
]
});
});
Documentation: https://docs.mongodb.com/realm/node/data-model
As of now there is no way to insert direct value in Realm database without key so for now we need to modify data and then we can store in following schema.
const ParentSchema = {
name: "parent",
properties: {
a: "level[]"
}
};
const level = {
name: 'level',
properties: {
level: 'sites[]'
}
}
const sites = {
name: 'sites',
properties: {
sites: 'site[]'
}
}
const site = {
name: 'site',
properties: {
title: 'string?',
_id: 'string?',
version: 'int?',
}
}
Data modification need to done like following.
var a = {
level: []
}
data.a.map((Site, index) => {
const sites = []
Site.map((s) => { sites.push(s)})
a.level.push({sites})
})

React Axios Get Call to Output JSON Format

I am performing an Axios get call in a React Component to retrieve JSON info. That function is working great. Within the JSON is a label for various network ports, which are returning as an array in my axios call. These are ultimately going to be displayed as nodes on a d3 graph. My issue is that I need to output the data pulled from the get call into the following format:
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
So the full component for the graph to read is:
export const data = {
nodes: [
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' },
{ id: 'JSON data.label here' }
]
}
Here is the format of the Axios get I am using:
axios.get(`NetworkConstruct.json`)
.then(res => {
const names = res.data.items;
this.setState({ names });
});
Here is a sample output I am receiving (there are 11 of these):
{id: "5bc0860c-ece1-461c-bac0-b155a3cacd82", label: "80.107.0.212",
resourceTypeId: "tosca.resourceTypes.NetworkConstruct", productId:
"5bc0835c-6cfa-486e-8429-a59eaf4118bc", tenantId: "393fa8da-61fd-458c-80f9-
ce92d0ef0330", …}
The data has to be in this EXACT format or the graph won't read it. I'm guessing I'll need to do an initial map function but am stuck on how to arrange it. I cannot have any divs or quotes in my output. Is this doable? I have scoured the boards and Google for a couple of days and can't make this work yet.
Here is the object I am receiving from the GET request.
{
"id": "5bd2c6ef-6009-4b90-9156-62168f3c6293",
"resourceId": "5bd0ba82-2994-455d-8716-2adb5694d6f0",
"interface": "getGraph",
"inputs": {},
"outputs": {
"graph": {
"nodes": [
{
"id": "5bcdf06c-dd53-4335-840f-55a4b8d85a2d",
"name": "asw-lab9306b",
"ports": {
"GigabitEthernet3/0/8": "5bd1777f-0ab9-4552-962b-9e306ce378ab",
"GigabitEthernet2/0/15": "5bd1777e-119c-44e8-ba69-0d86a481c0f5",
"GigabitEthernet3/0/47": "5bd17783-be94-4aaf-8858-70e4eb3d02dc",
"GigabitEthernet2/0/13": "5bd17783-ed99-453f-a958-f764edaa8da8"
}
}
],
"links": [
{
"a": "5bd1a467-13f2-4294-a768-561187b278a8",
"z": "5bd17770-2e6c-4c37-93c8-44e3eb3db6dd",
"layer": "ETHERNET"
},
{
"a": "5bd1776e-c110-4086-87d6-a374ccee419a",
"z": "5bd17770-83ee-4e10-b5bb-19814f9f5dad",
"layer": "ETHERNET"
}
]
}
},
"state": "successful",
"reason": "",
"progress": [],
"providerData": {},
"createdAt": "2018-10-26T07:49:03.484Z",
"updatedAt": "2018-10-26T07:49:25.425Z",
"resourceStateConstraints": {},
"executionGroup": "lifecycle"
}
The info I need is the nodes ID. There are eleven of them in the full object.
You can map an array of objects to another array of objects in your format with Array.prototype.map(). Assuming that data is the list of objects from your response:
class Graph extends React.Component {
state = {
nodes: null,
};
componentDidMount() {
axios.get('the url').then(response => {
const nodes = response.data.outputs.graph.nodes;
this.setState({nodes});
});
}
render() {
const {nodes} = this.state;
if (!nodes) return 'Loading...'
return <TheD3ComponentYouUse nodes={nodes} />;
}
}

Binding of a Collection nested inside a Model

I have this model structure in my mind:
var app = app || {};
// Caratteristica
app.Attribute = Backbone.Model.extend({
defaults: {
name: '',
selected: false
}
});
app.Attributes = Backbone.Collection.extend({
model: app.Attribute
});
// Tipo Caratteristica
app.AttributeCategory = Backbone.Model.extend({
defaults: {
name: '',
attributes: new app.Attributes()
}
});
app.AttributeCategories = Backbone.Collection.extend({
model: app.AttributeCategory,
url: '/ajax/attributes.cfm'
});
My API in '/ajax/attributes.cfm' will give me a response like that:
[
{
"id": "1",
"name": "Type1",
"attributes": [
{
"id": "1",
"name": "Attribute1"
},
{
"id": "2",
"name": "Attribute2"
},
{
"id": "3",
"name": "Attribute3"
}
]
},
{
"id": "2",
"name": "Type2",
"attributes": [
{
"id": "1234",
"name": "Attribute1234"
},
{
"id": "2567",
"name": "Attribute2567"
}
]
}
]
My question is: will this json data be parsed correctly into my nested data structure?
I mean I want to end up having two app.AttributeCategory items in my app.AttributeCategories collection. Each of these two items must then have its attributes property filled with the corresponding app.Attributes collection.
If the answer was NO, how would I override the parse() function for achieving that result?
I did it like this:
// Tipo Caratteristica
app.AttributeCategory = Backbone.Model.extend({
defaults: {
name: ''
},
initialize: function(options) {
this.set('attributes', new app.Attributes(options.attributes));
Backbone.Model.prototype.apply(this, arguments);
}
});
But better use RationalModel for set up relations betweens models
You can create the collection inside an initialize method in your AttributeCategory model, like this:
app.AttributeCategory = Backbone.Model.extend({
...
initialize: function () {
this.set('attributes', new app.Attributes(this.get('attributes')));
}
});

Resources