This might be the noobiest Strapi or possibly backend question at all, but I have just started doing backend, so please bear with me.
That being said, I have the following case. I am building an online shop and every product I have has a price (a required field) and new_price (optional). When I filter my API by min-max value, I would like to filter price if new_price is not available and new_price if it is available. Is this possible at all in strapi?
{
id: 2,
attributes: {
name: "My name",
createdAt: "2022-01-15T11:28:46.138Z",
updatedAt: "2022-02-16T10:38:20.412Z",
publishedAt: "2022-01-15T11:29:30.306Z",
description: "Lorem ipsum",
item_code: "688002",
slug: "some-slug-here",
available: true,
price: 59,
new_price: 21.9
}
http://localhost:1337/api/products?filters[price || new_price][$gte]=50
You're answer is perfectly fine. Just posted my full implementation here so that it may help others who stumble upon it.
const qs = require("qs");
const query = qs.stringify(
{
filters: {
$or: [
{
$and: [
{ new_price: { $notNull: true } },
{ new_price: { $gte: minPrice } },
{ new_price: { $lte: maxPrice } },
],
},
{
$and: [
{ new_price: { $null: true } },
{ price: { $gte: minPrice } },
{ price: { $lte: maxPrice } },
],
},
],
},
},
{
encodeValuesOnly: true,
}
);
await request(`/api/books?${query}`);
So I came up with this solution. It might be ugly and not how it's done, but it works, and I couldn't think of anything else. If somebody has a better solution, I will greatly appreciate it!
const query = qs.stringify(
{
populate: '*',
pagination: {
page: page,
pageSize: PER_PAGE
},
filters: {
$or: [
{
$and: [
[
{
new_price: {
$null: true
}
},
{
price: {
$gte: minPrice
}
},
{
price: {
$lte: maxPrice
}
}
]
]
},
{
$and: [
[
{
new_price: {
$notNull: true
}
},
{
new_price: {
$gte: minPrice
}
},
{
new_price: {
$lte: maxPrice
}
}
]
]
}
]
}
},
Related
I need to implement a scenario where type ahead search makes a call to my remote api and fills in the choice list. This works fine the if adaptive card is sent directly in the chat. But this not work inside if the adaptive card is sent in the task module.
Steps
Following is the message which is sent for adaptive card
const card = CardFactory.adaptiveCard({
type: 'AdaptiveCard',
body: [
{
type: 'RichTextBlock',
inlines: [
{
type: 'TextRun',
text: 'Test',
weight: 'bolder',
},
{
type: 'TextRun',
text: 'Test',
}
],
separator: parseInt(index) === 0,
spacing: parseInt(index) === 0 ? 'extraLarge': 'default',
},
{
title: 'Update',
type: 'Action.Submit',
data: {
msteams: {
type: 'task/fetch'
},
id: 'Upate Id',
buttonText: 'Update',
}
}
],
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
})
Following is card which is sent in task module
const card = CardFactory.adaptiveCard({
$schema: 'http://adaptivecards.io/schemas/adaptive-card.json',
version: '1.5',
type: 'AdaptiveCard',
body: [
{
"columns": [
{
"width": "stretch",
"items": [
{
"choices": [
{
"title": "Static Option 1",
"value": "static_option_1"
},
{
"title": "Static Option 2",
"value": "static_option_2"
},
{
"title": "Static Option 3",
"value": "static_option_3"
}
],
"isMultiSelect": false,
"style": "filtered",
"choices.data": {
"type": "Data.Query",
"dataset": "npmpackages",
"testkey": "harkirat"
},
"id": "choiceselect",
"type": "Input.ChoiceSet"
}
],
"type": "Column"
}
],
"type": "ColumnSet"
}
],
actions: [
{
type: 'Action.Submit',
title: 'Save',
data: {
privateMeta,
replyToId
}
}
]
});
Following is the onActivityInvoke code:-
async onInvokeActivity(context: TurnContext): Promise<InvokeResponse<any>> {
if (context.activity.name === 'task/fetch') {
const result = await this.handleTeamsTaskModuleFetch(context, {
replyToId: context.activity.replyToId,
data: context.activity.value.data
});
return {
status: 200,
body: result
}
}
if (context.activity.name == 'application/search') {
const successResult = {
status: 200,
body: {
"type": "application/vnd.microsoft.search.searchResponse",
"value": {
"results": [
{
"value": "FluentAssertions",
"title": "A very extensive set of extension methods"
},
{
"value": "FluentUI",
"title": "Fluent UI Library"
}
]
}
}
}
return successResult;
}
}
Note that the activityInvoke function is not called when I enter the search text in my input box. However, if I send this card directly i.e without task module and directly in chat it works just fine.
Can someone please help me understand if I am missing something, is this a bug or the feature itself is not supported?
I been trying to load datas from elasticsearch into combobox but unsuccessfully, however load datas from json file to combobox it work.
the only different that is that load data from the store on json file, it successfully loaded the data, but when for elasticsearch, it reply '400: Bad Request'
[Json File]
[
{
"index":"color",
"_type":"_doc",
"_id":1,
"_score":1.0,
"_source":
{
"name":"Red"
}
},
{
"index":"color",
"_type":"_doc",
"_id":2,
"_score":1.0,
"_source":
{
"name":"Blue"
}
}
]
[ElasticSearch Json Reply]
{
"took":3,
"timed_out":false,
"_shards":
{
"total":1,
"successful":1,
"skipped":0,
"failed":0
},
"hits":{
"total":{
"value":4,
"relation":"eq"
},
"max_score":1.0,
"hits":[
{
"_index":"color",
"_type":"_doc",
"_id":1,
"_score":1.0,
"_source":{
"name":"Red"
}
},
{
"_index":"color",
"_type":"_doc",
"_id":2,
"_score":1.0,
"_source":{
"name":"Blue"
}
},
{
"_index":"color",
"_type":"_doc",
"_id":3,
"_score":1.0,
"_source":{
"name":"Green"
}
},
{
"_index":"color",
"_type":"_doc",
"_id":4,
"_score":1.0,
"_source":{
"name":"Yellow"
}
}
]
}
}
My Model Code
Ext.define('MyApp.model.ColorModel',{
extend: 'Ext.data.Model',
alias: 'model.colormodel,
requires: [
'Ext.data.field.String',
'Ext.data.field.Integer'
],
fields: [
{
type:'string',
name:'_index'
},
{
type:'string',
name:'_type'
},
{
type:'string',
name:'_id'
},
{
type:'int',
name:'_score'
},
{
name:'_source'
},
]
});
My Store Code [Json File- That Work]
Ext.define('MyApp.store.ColorStore',{
extend: 'Ext.data.Store",
requires: [
'MyApp.model.ColorModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cgf || {};
me.callParent([Ext.apply({
storeId:'ColorStore',
model:'MyApp.model.ColorModel',
proxy: {
type:'ajax',
url: 'http://localhost:8888/data/color.json,
withCredentials:true,
reader: {
type:'json'
}
}
}, cfg)]);
}
});
[My Another Store that retrieve from elasticsearch] - not working
Ext.define('MyApp.store.ESColorStore',{
extend: 'Ext.data.Store",
requires: [
'MyApp.model.ColorModel',
'Ext.data.proxy.Ajax',
'Ext.data.reader.Json'
],
constructor: function(cfg) {
var me = this;
cfg = cgf || {};
me.callParent([Ext.apply({
storeId:'ESColorStore',
model:'MyApp.model.ColorModel',
proxy: me.processMyAjaxProxy1({
type:'ajax',
read: function(operation, callback, scope){
var request = this.bulidRequest(operation, callback,scope);
var query = {
"from": operation.params.from,
"size": operation.params.size,
"query": {
"query_string" : { }
},
"sort": [
{
"name.raw":{
"order": "asc"
}
}
]
};
Ext.apply(request, {
headers: this.headers,
timeout: this.timeout,
scope: this,
callback: this.createRequestCallback(request,operation,callback,scope),
method: 'POST',
params: operation.params,
jsonData: query,
disableCaching:true,
success: function(rec) {
console.log('[ESColorStore], successfully retrieved query: ' + rec.responseText);
}
failure: function(rec) {
console.log('[ESColorStore], failed retrieved query: ' + rec.responseText);
}
});
Ext.Ajax.request(request);
return request;
},
reader: {
type:'json'
}
}
}, cfg)]);
},
proccessMyAjaxProxy1: function(config) {
config.api = {
read: 'http://localhost:9200/color/_search'
};
config.url = 'http://localhost:9200/color/';
return config
},
});
[Views]
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.Panel',
alias: 'widget.mypanel',
requires: [
'MyApp.view.MyPanelViewModel',
'Ext.field.ComboBox'
],
viewModel: {
type: 'mypanel'
},
title: 'My Panel',
items: [
{
xtype:'comobobox',
name:'select-the-color',
width: 419,
docked: 'top',
label:'Select The Color',
autoLoadOnValue: true,
displayField: '_source.name',
selectOnTab:false,
store:'ESColorStore',
valueField:'_source.name',
queryCaching: false,
queryParam:''
}
]
});
I recently made the switch with Vuelidate from Vee-Validate a few weeks ago for all our apps and have been loving its flexibility so far; however, I've run across an issue that I'm not quite sure how to solve...
I've added the (primitive) example, using my real data here:
https://jsfiddle.net/80cuuagp/18/
From the fiddle:
new Vue({
el: "#app",
data() {
return {
questions: [
{
message: '1. Do you expect to conduct cash transactions for this account? ',
value: false,
conditionalFields: [
{
title: 'Cash In',
fields: [
{ label: 'Total Amount', value: '' },
{ label: 'Frequency', value: '' }
]
},
{
title: 'Cash Out',
fields: [
{ label: 'Total Amount', value: '' },
{ label: 'Frequency', value: '' }
]
}
]
},
{
message: '2. Will Electronic (ACH) transactions be processed on the account (excluding card transactions)?',
value: false,
conditionalFields: [
{
title: 'Electronic Deposits',
fields: [
{ label: 'Total Amount', value: '' },
{ label: 'Frequency', value: '' }
]
},
{
title: 'Electronic Withdrawals',
fields: [
{ label: 'Total Amount', value: '' },
{ label: 'Frequency', value: '' }
]
}
]
},
{
message: '3. Will Domestic Wires be sent or received from the account?',
value: false,
conditionalFields: [
{
fields: [
{ label: 'Frequency of Incoming Wires', value: '' }
]
},
{
fields: [
{ label: 'Frequency of Outgoing Wires', value: '' },
]
}
]
},
{
message: '4. Will International Wires be sent or received from the account?',
value: false,
conditionalFields: [
{
fields: [
{ label: 'Frequency of Incoming Wires', value: '' }
]
},
{
fields: [
{ label: 'Frequency of Outgoing Wires', value: '' },
]
}
]
},
{
message: '5. Will Monetary Instruments (CC/MO) be issued from the account?',
value: false,
conditionalFields: [
{
fields: [
{ label: 'Total Amount', value: '' }
]
}
]
}
]
}
},
validations: {
questions: {
$each: {
conditionalFields: {
$each: {
fields: {
$each: {
value: { required }
}
}
}
}
}
}
}
})
The problem is - I'm conditionally rendering fields based on the user's input. If he or she selects "Yes" to any of the questions, a secondary fieldset will appear below it and ask for input. These fields are only required if yes is selected and they appear on the DOM (and will also have different validations, which I'm not sure how to address, either without hard-coding everything). I've tried looping through the data by making validations a function, but even though it seems to compile, it's not dynamically adding any validations based on the question[index].value being set to true.
I feel like there has to be a simple way to do this, but I'm definitely overthinking it at this point. Any help would be greatly appreciated!
Thanks!
My sampleJSON -
{
"entries": [
{
"fields":{
"title":"My test title"
}
},
{
"fields":{
"description":"My test description"
}
}
]
}
Schema.js -
const rootQuery = new GraphQLObjectType({
name: 'testQuery',
fields: {
Articles: {
type: articleItem,
resolve(parentValue) {
return axios.get(`/getArticles`).then(resp => resp.data);
}
}
}
});
const articleItem = new GraphQLObjectType({
name: 'articleItem',
fields: () => ({
entries: {type: new GraphQLList(entry)}
})
});
const entry = new GraphQLObjectType({
name: 'entry',
fields: () => ({
fields: {type: fields}
})
});
const fields = new GraphQLObjectType({
name: 'fields',
fields: () => ({
title: {type: GraphQLString},
description: {type: GraphQLString}
})
});
GraphQL query i am using to query the data in the above JSON -
query articles{
Articles {
entries{
fields{
title,
description
}
}
}
}
I am wondering why the query returns "title" even though it is null in the second object and likewise with description in the first object. Is there a way to just return " title " or " description " only if it not null?
Current result of the query -
{
"data" : {
"entries" [
{
"fields": {
"title": "My test title",
"description": null
}
},
{
"fields": {
"title": null,
"description" : "My test description"
}
}
]
}
}
Required result -
{
"data" : {
"entries" [
{
"fields": {
"title": "My test title"
}
},
{
"fields": {
"description" : "My test description"
}
}
]
}
}
Appreciate any help with this !, thanks.
Way too late to answer, but if you stumble upon this, you can make non-nullable (!) by using GraphQLNonNull().
Here is the example for non-nullable integer
random: {
type: new GraphQLNonNull(GraphQLInt)
}
I have the following object that contains 2 fixed attributes (OrderId and Purchasedate, and an array of attribues. I try to to put this in ng-repeat with orderBy option. The first 2 attribute (OrderId and PurchaseDate) work OK when sorting is applied by clicking on the header. However I do not get it working on the 3 rd attribute and so on.
The rows shown on the table are correct.
The object looks like
e.g.
$scope.orders;
[
{ OrderId: "P888291", PurchaseDate : "2016-12-02",
Items: { elt : [ { Name: "City", Value: "New York"}, { Name: "Street", Value: "Broadway 5" }, { Name: "Country", Value: "USA" } ] } },
{ OrderId: "P334498", PurchaseDate : "2016-11-02",
Items: { elt : [ { Name: "City", Value: "London" }, { Name: "Street", Value: "WestMinister 3" }, { Name: "Country", Value: "Great Brittain" } ] } },
{ OrderId: "G393383", PurchaseDate : "2016-11-28",
Items: { elt : [ { Name: "City", Value: "Milan" }, { Name: "Street", Value: "Pizza 8" }, { Name: "Country", Value: "Italy" } ] } },
{ OrderId: "P978381", PurchaseDate : "2015-05-25",
Items: { elt : [ { Name: "City", Value: "Seattle" }, { Name: "Street", Value: "Houston 9" }, { Name: "Country", Value: "US" } ] } },
{ OrderId: "P983394", PurchaseDate : "2015-06-05",
Items: { elt : [ { Name: "City", Value: "Amsterdam" }, { Name: "Street", Value: "Damrak 5" }, { Name: "Country", Value: "Netherlands" } ] } },
{ OrderId: "G678994", PurchaseDate : "2015-04-01",
Items: { elt : [ { Name: "City", Value: "The Hague" }, { Name: "Street", Value: "Markt 22" }, { Name: "Country", Value: "Netherlands" } ] } },
{ OrderId: "P128994", PurchaseDate : "2016-12-04",
Items: { elt : [ { Name: "City", Value: "The Hague" }, { Name: "Street", Value: "Plein 7" }, { Name: "Country", Value: "Netherlands" } ] } },
];
Please advise and the code is put in :
http://www.w3schools.com/code/tryit.asp?filename=FAG7BWVK8BYH
You can try with custom filter logic.(https://docs.angularjs.org/api/ng/filter/orderBy )
for example:
JS:
$scope.filterOrderFn = function(orderobj)
{
// Do
if(...)
{
return _something_// this will be your sorted order according to your first condition
}
else if(...)
{
return _something_ // this will be your sorted order according to your second condition if require
}
return false; // otherwise it won't be within the orderlist
};
HTML:
...
<article data-ng-repeat="order in orders | orderBy:filterOrderFn" class="order">
...
If you need a very specific ordering behaviour you could write your own filter (although orderBy should be enough for most uses cases). As you may know you can chain many filters together, so adding your custom filter function doesn't force you to remove the previous filter using the search object (they will work together seamlessly).