I'm trying to do a JSON.mapping in a class (OtherThing) based on the merge of two named tuples.
class Thing
MAPPING = {
id: {type: String, default: UUID.random.to_s},
email: {type: String, nilable: true},
}
JSON.mapping({{MAPPING}})
end
class OtherThing
MAPPING = Thing::MAPPING.merge({
address: String,
city: String,
zip: {type: String, nilable: true},
latitude: {type: Float64, nilable: true},
longitude: {type: Float64, nilable: true},
})
JSON.mapping({{MAPPING}})
end
This produces an error depending on how I organize the code.
One error:
Error expanding macro
FOR expression must be an array, hash or tuple literal, not Call:
Thing::MAPPING.merge
{% for key, value in _properties_ %}
^~~~~~~~~~~~
Another possible error:
undefined macro method 'NamedTupleLiteral#merge' in the JSON.mapping of OtherThing
In short answer — no, you can't interpolate constant in macro right now.
#asterite:
The problem is that the mapping macros expect a HashLiteral as an
argument, but now they receive a Path
In you case instead NamedTuple macro got the Call node. In discuss on Crystal repo https://github.com/crystal-lang/crystal/issues/2388 found workaround that in theory can solve this problem but JSON.mapping it is old method and will be removed from language in next versions, instead try to JSON::Serializable
Thanks to #Blacksmoke16 for his help in pointing that, you can achieve desired outcome by defining your own macro with splats.
Below code should work. Credit goes to #Blacksmoke16
macro define(*args)
JSON.mapping(
{% for t in args %}
{{t.double_splat}},
{% end %}
)
end
class Thing
MAPPING = {
id: {type: String, default: UUID.random.to_s},
email: {type: String, nilable: true},
}
define {{MAPPING}}
end
class OtherThing
MAPPING = {
address: String,
city: String,
zip: {type: String, nilable: true},
latitude: {type: Float64, nilable: true},
longitude: {type: Float64, nilable: true},
}
define {{MAPPING}}, {{Thing::MAPPING}}
end
Related
What I am trying to do
I have a type of Category and a type of Product. I want to be able to filter the products, by the category. For example, I want to be able to see only the products that are of Category "Mixed Drink". When in Apollo Studio I am unable to do this.
What I tried
This is in my TypeDef file
type Category {
id:ID
name: String
product: [Product]
},
type Product {
id: ID
name: String
description: String
ingredients: [String]
moveActive: Boolean
price: Float
category: [Category]
},
input productsByCategoryFilter {
id: ID
name: String
description: String
ingredients: [String]
moveActive: Boolean
price: Float
}
type Query {
productsByCategory(category: productsByCategoryFilter): [Product]
},
What I thought this would do is create an input field that I could put as an argument to get back an array of all the products. However, this isn't working.
Here is my resolver function for this.
productsByCategory:(_parent:any, {category}, context: Context) => {
return context.prisma.product.findMany({
where: {
category
}
})
}
Any information would be helpful!
I have a simple question, I have dummy data about some products and I need to take all categories into the new list. How can I do it?
class Products with ChangeNotifier {
List<Product> _productItems = [
Product(
id: 'p1',
title: 'Red Shirt',
price: 29.99,
category: 'shirts',
),
Product(
id: 'p2',
title: 'Trousers',
description: 'A nice pair of trousers.',
price: 59.99,
category: 'Trousers',
),
Product(
id: 'p3',
title: 'Yellow Scarf',
price: 19.99,
category: 'Scarfs',
),
Product(
id: 'p4',
title: 'A Pan',
price: 49.99,
category: 'Pans',),];
List<Product> get items {
return [...items];
}
List<Product> get fovoriteItems {
return _productItems.where((prodItem) => prodItem.isFavorite!).toList();
}
List<Product> get stockItems {
return _productItems.where((prodItems) => prodItems.isStock!).toList();
}
List<Product> get categoriesList {}
}
I need to take a List like categories = [Shirts,Trousers,Scarfs,Pans];
Your problem isn't clear but there are notable issues in your code. You firstly need to update your items method to return all the products. So update it to something like this:
List<Product> get items {
return _productItems;
}
Then in the get favoriteItems method, you have not defined the isFavorite property in any of the dummy classes. So update them to include it. This also goes for your get stockItems method. Here's an example:
Product(
id: 'p9',
title: 'Apples',
description: 'A delicious red treat',
price: 1.99,
category: 'Food',
isFavorite: false,
isStock: true,
),
Also make sure to remove the ! from prodItem.isFavorite! and prodItems.isStock! because this will give the opposite result.
The categoriesList method should be of type String because a category isn't necessarily product. Here's the implementation:
List<String> get categories {
List<String> ctgrs = [];
for (item in _productItems) {
ctgrs.add(item.category);
}
return ctgrs;
}
I would also highly recommend using UniqueKey() or using the UUID package for every product's id so you don't have to make a custom one for every product. Using UUID is very secure as well.
List<String> categories = [];
_productItems.forEach((element) {
if (categories.indexOf(element.category) < 0) {//avoid duplicates
categories.add(element.category);
}
});
What is the correct syntax for saving latitude and longitude in Baqend?
I am successfully saving the normal fields (all of them are strings):
handleSubmit(event) {
event.preventDefault();
var newcompany = new db.Companies({
name: this.state.name,
photo: '',
geo: '47.626814;-122.357345',
address1: this.state.address1,
address2: this.state.address2,
city: this.state.city,
state: this.state.state,
zip: this.state.zip,
});
newcompany.insert().then(() => {
//console.log(newcompany)
this.setState({
redirect: true,
newcompanykey: newcompany.key
})
})
}
But I can't seem to get the geo to save correctly. Probably because I'm treating it as a string and that is not correct?
In the example code I'm just hardcoding it now to values I know are good so we can get this working.
I think the answer here is that the sdk provides a function that encodes it correctly:
handleSubmit(event) {
event.preventDefault();
var geo = new db.GeoPoint(47.626814, -122.357345)
var newcompany = new db.Companies({
name: this.state.name,
photo: '',
geo: geo,
address1: this.state.address1,
address2: this.state.address2,
city: this.state.city,
state: this.state.state,
zip: this.state.zip,
});
newcompany.insert().then(() => {
//console.log(newcompany)
this.setState({
redirect: true,
newcompanykey: newcompany.key
})
})
}
I have a object, which has multiple objects
fields:[
{
safeName: 'status',
accessorName: 'Status',
type: {name: 'String', doc: 'String', code: '\'String\''},
field: {type: 'string', description: 'pet status in the store', enum: ['available', 'pending', 'sold']}
},
{
safeName: 'code',
accessorName: 'Code',
type: {name: 'NSInteger', doc: 'NSInteger', code: '\'NSInteger\'' },
field: {type: 'integer', format: 'int32'}
},
...
]
I need to check with enum value
Output should be
When enum is present in field
instance.status = Order.Status(rawValue: (sourceDictionary["status"] as? String) ?? "")
And when enum is not present in field object
instance.code = Decoders.decodeOptional(clazz: NSInteger.self, source: sourceDictionary["code"])
Did like this
{{#fields}}{{#field}}
{{#description}}
instance.{{safeName}} = Order.Status(rawValue: (sourceDictionary["{{safeName}}"] as? String) ?? "")
{{/description}}
{{^description}}
instance.{{safeName}} = Decoders.decodeOptional(clazz: {{#type}}{{type.name}}{{/type}}.self, source: sourceDictionary["code"])
{{/description}
{{/field}}{{/fields}}
I'm a completely new to emberjs but excited to get in and play around. One thing I'm struggling with is ... can you load a JSON object that has an object graph depth of more than 1. What I mean is is it seems relatively straight forward to set a Model to a series of name/value pairs where the value is a simple type (string, integer, date, etc.) but what if it's an object?
I imagine it might be connected to the relationship model but from what I see in the documentation this only allows for a FK->PK relationship and not an inline object. I'm probably doing a terrible job of explaining what I mean so let me give you an example:
Let's assume that I have a REST call at the endpoint of: http://my.url.com/place/[place_id] and the GET call returns:
{
place: {
name: "string",
desc: "string",
location: {
longitude: float,
latitude: float,
radius: int
}
}
In the above example I am struggling to understand how to model location. Any help on how to extend this would be greatly appreciated:
App.Place = DS.Model.extend({
name: "string",
desc: "string",
location: "?????"
});
You can introduce a new data transform to handle raw JSON.
DS.RESTAdapter.registerTransform('raw', {
deserialize: function(serialized) {
return serialized;
},
serialize: function(deserialized) {
return deserialized;
}
});
Now you cab define your model with raw as the data type for location.
App.Place = DS.Model.extend({
name: DS.attr('string'),
desc: DS.attr('string'),
location: DS.attr('raw')
});
If your data from the server has the form
place: {
id: 'place',
name: 'foo',
desc: 'bar',
location: {
longitude: 1,
latitude: 2,
radius: 3
}
}
then you can bind to location.longitude, etc. in your template. Here is is fleshed out in a jsfiddle.