I'm developing an angular project with the mock server json-server. GET is working correctly, but now I'm having some problems with POST.
I've defined this file interventi.json with these data:
{
"interventi":[
{
"codice": "123",
"codiceUso": 897,
"dataIntervento": "21-06-2019",
"dataInserimento": "24-06-2019",
"cooperativa": "Example",
"puntoVendita": "Example",
"tipiAttivita": [
"Prelievo",
"Sanzione"
],
"organoCompetente": "Ex"
},
{
"codice": "456",
"codiceUso": 823764,
"dataIntervento": "24-06-2019",
"dataInserimento": "29-06-2019",
"cooperativa": "Example 2",
"puntoVendita": "Example 2",
"tipiAttivita": [
"Prelievo"
],
"organoCompetente": "Ex"
}
]
}
I'm trying to post this json:
{
"codice":"a7spx",
"codiceUso":"123",
"dataIntervento":"2019-06-21T12:58:09.345Z",
"cooperativa":"2",
"puntoVendita":2,
"tipiAttivita":[
"Attivita 1",
"Attivita 2"
],
"organoCompetente":3,
"dataInserimento":"2019-06-21T12:58:09.345Z"
}
but it's giving me 500 internal server error:
"TypeError: Cannot read property 'id' of undefined
at Function.createId (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\json-server\lib\server\mixins.js:47:39)
at Function.insert (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\lodash-id\src\index.js:47:49)
at C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\lodash\lodash.js:4374:28
at arrayReduce (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\lodash\lodash.js:683:21)
at baseWrapperValue (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\lodash\lodash.js:4373:14)
at LodashWrapper.wrapperValue (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\lodash\lodash.js:9052:14)
at create (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\json-server\lib\server\router\plural.js:225:50)
at Layer.handle [as handle_request] (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\express\lib\router\layer.js:95:5)
at next (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\express\lib\router\route.js:137:13)
at next (C:\Users\Marina\coop-workspace\wqrng\web\src\main\angular\wqrng\node_modules\express\lib\router\route.js:131:14)"
I've followed this tutorial to do post, and saw that field id is not mandatory, but server is complaining. If I add id field in my json, it works correctly. But I don't want id in my entities, is there a way to disable this behaviour?
EDIT
// Return incremented id or uuid
// Used to override lodash-id's createId with utils.createId
function createId(coll) {
var _ = this;
var idProperty = _.__id();
if (_.isEmpty(coll)) {
return 1;
} else {
var id = _(coll).maxBy(idProperty)[idProperty];
// Increment integer id or generate string id
return _.isFinite(id) ? ++id : nanoid(7);
}
}
If you are using any id other then default "id" you have explicitly configure it using json-server CLI.
--id, -i Set database id property (e.g. _id) [default: "id"]
Check following link
https://github.com/typicode/json-server#cli-usage
Related
Set values based on the ip address in JSON with if the else
Using perl JSON module.
I'm trying to setup my etc/config.json so that I never have to edit it when I move code from development->staging->production.
sql ip addresses will be different for different VM's
{
"html_title" : "Bogus",
"local_ip" :
"default" : "[production]",
"hosts" :
{
"production" :
{
"10.11.12.13" : "b102-vm",
"10.11.12.14" : "b103-vm"
},
"stage" :
{
"10.11.12.15" : "b102-vm-s",
"10.11.12.16" : "b103-vm-s"
},
},
"production" :
{
"some_schema" :
{
"host" : "10.11.12.13",
"database" : "some_table",
"dsn" : "DBI:mysql:[production.some_schema.database]:[production.some_schema.host]",
"user" : "user",
"pass" : "pass"
}
},
"stage" :
{
"some_schema" :
{
"host" : "10.11.12.16",
"database" : "some_table",
"dsn" : "DBI:mysql:[stage.some_schema.database]:[stage.some_schema.host]",
"user" : "user",
"pass" : "pass"
}
},
"if" : HERE IS WHERE I GET LOST.
{
"local_ip" : {
"anyOf" : ["[hosts.production]"]
}
},
"then" : { "default" : "[production]" }
"else" :
{
"if" :
{
"local_ip" : {
"anyOf" : ["[hosts.stage]"]
}
},
"then" : { "default" : "[production]" }
}
}
Would like to see "default" point to the production or stage values
As others have pointed out in the comments, JSON is not a programming language; it is a data storage format.
I can think of two obvious ways to do this. Yours is, I'm sorry to say, not one of them.
Both of my solutions involve your various systems having an environment variable set which identifies the kind of environment it is. I'm also going to assume some kind of get_config() function that reads a config file and returns a Perl data structure of the config.
Solution 1: Separate files
Have two files called "staging.json" and "production.json". The get_config() function reads the required one.
sub get_config {
my %valid_env = (
staging => 1,
production => 1,
);
die "$ENV{ENVIRONMENT} is not a valid environment type\n"
unless $valid_env{$ENV{ENVIRONMENT}};
my $json = read_file("$ENV{ENVIRONMENT}.json");
return JSON->new->decode($json);
}
As an extension to this, you could have three files - common.json, staging.json and production.json. You'd always read common.json along with the correct environment file and merge the two data structures into one before returning the data.
Solution 2: Munge the config
Stick with your existing file but munge the data structure after you've read it and before you return it.
sub get_config {
my %valid_env = (
staging => 1,
production => 1,
);
die "$ENV{ENVIRONMENT} is not a valid environment type\n"
unless $valid_env{$ENV{ENVIRONMENT}};
my $json = read_file('config.json');
my $config = JSON->new->decode($json);
# Use $ENV{ENVIRONMENT} to munge the contents of $config
# so it only contains data about the current environment
return $config;
}
Trying to create a new jira ticket of specific requestType, but it is nested two levels deep. Tried few possible alterations, but no luck. Here's the code I have,
require 'jira-ruby' # https://github.com/sumoheavy/jira-ruby
options = {
:username => jira_username,
:password => jira_password,
:site => 'https://jiraurl/rest/api/2/',
:context_path => '',
:auth_type => :basic,
:read_timeout => 120
}
client = JIRA::Client.new(options)
issue = client.Issue.build
fields_options = {
"fields" =>
{
"summary" => "Test ticket creation",
"description" => "Ticket created from Ruby",
"project" => {"key" => "AwesomeProject"},
"issuetype" => {"name" => "Task"},
"priority" => {"name" => "P1"},
"customfield_23070" =>
{
"requestType" => {
"name" => "Awesome Request Type"
}
}
}
}
issue.save(fields_options)
"errors"=>{"customfield_23070"=>"Operation value must be a string"}
Also tried passing a JSON object to customfield_23070,
"customfield_23070": { "requestType": { "name": "Awesome Request Type" } }
still no luck, get the same error message.
If it helps, this is how customfield_23070 looks like in our Jira,
Does anyone know how to set requestType in this case, please? Any help is greatly appreciated!!
It seems that for custom fields with specific data types (string/number), you must pass the value as:
"customfield_1111": 1
or:
"customfield_1111": "string"
instead of:
"customfield_1111":{ "value": 1 }
or:
"customfield_1111":{ "value": "string" }
I'm not sure but you can try this possible examples:
eg.1:
"customfield_23070"=>{"name"=>"requestType","value"=>"Awesome Request Type"}
eg.2:
"customfield_23070"=>{"requestType"=>"Awesome Request Type"}
eg.3:
"customfield_23070"=>{"value"=>"Awesome Request Type"}
eg.4
"customfield_23070"=>{"name"=>"Awesome Request Type"}
for ref there are 2 methods depending upon the fields you are interacting with
have a look here '
updating-an-issue-via-the-jira-rest-apis-6848604
' for the applicable fields for update via verb operations, the other fields you can use examples as per above,
you can use both methods within the same call
{
"update": {"description": [{"set": "Description by API Update - lets do this thing"}]},
"fields": {"customfield_23310": "TESTING0909"}
}
Ok, I think I found how to do it.
You need to provide a string, and that string is the GUID of the RequestType.
In order to get that GUID. You need to run the following in a scriptrunner console:
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.issueManager.getIssueByCurrentKey("ISSUE-400546") //Issue with the desired Request Type
def cf = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Tipo de solicitud del cliente") //Change it to the name of your request type field
issue.getCustomFieldValue(cf)
Source: https://community.atlassian.com/t5/Jira-Software-questions/how-to-set-request-type-value-in-while-create-jira-issue/qaq-p/1106696
Suppose I have a contract like this:
org.springframework.cloud.contract.spec.Contract.make {
request {
method "GET"
url "/api/profiles"
headers {
header('Accept': 'application/json;charset=UTF-8')
header('Content-Type': 'application/json;charset=UTF-8')
}
}
response {
status 200
headers {
header('Content-Type': 'application/json;charset=UTF-8')
}
body(
value(
stub(
'''\
[
{
"profile": "profile1",
},
{
"profile": "profile2",
}
]
'''
),
test(
[
[
"profile" : regex(nonEmpty()),
]
]
)
)
)
}
The test of "profile" : regex(nonEmpty()) only checks that there is at least one array entry with a profile attribute that is non empty.
I would like to test that all entries have a non-empty profile.
I already tried this using test matchers:
jsonPath('$.[*].profile', byRegex(nonEmpty()))
While this checks every profile field to be non-empty, it doesn't check whether such a field actually exists.
How can I test that a profile field exists in every array entry and that each one is non-empty?
I guess the easiest way will be to use byCommand in the testMatchers section and pass the list there. Then manually assert whatever you want programmatically.
Situation
In a project I have this code to select data from a table. Please note, it is working, I only don't get the result I expect.
serviceSurveyQuestions.find({
query: {
survey_id: this.survey_id,
user_id: this.$store.state.auth.user.id, //TODO move this to the hook!!
//todo make satus also not equal new
$or: [
{ status_id: process.env.mfp.statusSurveyQuestionStarted },
{ status_id: process.env.mfp.statusSurveyQuestionPlanned }
],
$sort: {
survey_question_question: 1
},
$limit: 150,
$select: [
'survey_question_question',
'survey_question_at',
'survey_question_answer',
'survey_question_details',
'survey_question_source_id',
'survey_question_source_answer_id',
'survey_question_source_user_id',
'survey_question_step',
'survey_question_dep_step',
'id'
]
}
}).then(page => {
this.listSurveyQuestions = page;
});
When I see what would be in one item of listSurveyQuestion I will see this:
{
"survey_question_question": "PEN 10 Scope vaststellen",
"survey_question_at": "2017-06-23T06:46:10.038Z",
"survey_question_answer": "",
"survey_question_details": "tester done",
"survey_question_source_id": 83499707,
"survey_question_source_answer_id": 74864,
"survey_question_source_user_id": 83488216,
"survey_question_step": 10,
"survey_question_dep_step": null,
"id": 4651,
"source_user": {
"user_id": 1005
},
"status": {
"status": "Planned"
},
"language": {
"language": "Dutch"
,
"source": {
"source": "MexonInControl - Pob - Dev (local)"
},
"survey_question": [{
"answer_type_id": 1014,
"answer_en": null,
"answer_nl": null,
"answer_explanation_en": null,
"answer_explanation_nl": null,
"survey_question_next_id": 4652
} ]
}
I know the result is comming from the configuration in my get and find hook of the service being called.
Expected Result
What I expect to happen is that the data returned is only the columns defined in the $SELECT. If I leave this as is, it will work but I'm getting to much data from the database which can be seen later as a security breach. Not with this example, but with other tables it will.
** Question **
So what do I need to change to have this functioning as expected. You could adapt the return of the service, but then I can't use the same service in other situations for the columns aren't available. Or can you pass an option to the service which will result in if (parameter = view 1) then return view 1 and so on.
** Solving **
Remark 1:
So I just see the 'cause' is a bit different. The configured hooks returns more columns from the question table which are not shown. So my guess here is that if you don't configure the includes in the find query, it will pass all includes. I need to check that and if this is the case, see if there is a option to not select the 'includes' as well.
Assuming that the hook you are referring to is setting hook.params.sequelize similar to this answer you will have to check if you included properties are also set in the $select query with something like this:
// GET /my-service?include=1
function (hook) {
const include = [];
const select = hook.params.query.$select;
// Go through all properties that are added via includes
['includeProp1', 'includeProp2'].forEach(propertyName => {
// If no $select or the include property is part of the $select
if(!select || select.indexOf(propertyName) !== -1) {
include.push({ model: ModelForIncludeProp1 });
}
});
hook.params.sequelize = { include };
return Promise.resolve(hook);
}
I'm trying to implement a filter based on the answer to this question, but it isn't working for me. For code:
function MyCtrl($scope, $timeout)
{
$scope.tweets = [
{
created_at: "Date",
text: "tweet text",
users:
[
{
name: "user name",
screen_name: "user screen name",
profile_image_url: "profile pic"
},
{
name: "user name 2",
screen_name: "user screen name 2",
profile_image_url: "profile pic"
}
]
},
{
created_at: "Date",
text: "tweet text 2",
users:
[
{
name: "user name",
screen_name: "user screen name",
profile_image_url: "profile pic"
},
{
name: "user name 2",
screen_name: "user screen name 2",
profile_image_url: "profile pic"
}
]
},
{
created_at: "Date",
text: "tweet text 3",
users:
[
{
name: "user name",
screen_name: "user screen name",
profile_image_url: "profile pic"
},
{
name: "user name 2",
screen_name: "user screen name 2",
profile_image_url: "profile pic"
}
]
}
];
}
and the template:
<div ng-app ng-controller="MyCtrl">
<div ng-repeat="tweet in tweets">
for each tweet, user 2's name should be printed here >>
{{(tweet.users | filter:{screen_name:'user screen name 2'}).name}}
_____________________________________
</div>
</div>
I'm seeing output of:
for each tweet, user 2's name should be printed here >>
for each tweet, user 2's name should be printed here >>
for each tweet, user 2's name should be printed here >>
I would expect that "user name 2" would be printed out after each ">>". I don't know why that filter isn't working on an array of each iterated element. Thanks.
fiddle
The filter doesn't return a user. It returns an array of users matching the filter condition. So in that case, an array containing one user.
So it should be
{{(tweet.users | filter:{screen_name:'user screen name 2'})[0].name}}
You could have found this yourself easily by just using
{{ (tweet.users | filter:{screen_name:'user screen name 2'}) }}
to see what the result of the filter was.
AND IF THE SAME USER IS MORE THAN ONCE ON THE SAME MESSAGE?
If you have more than one message from one user, the above answer will not work and, instead, will display something strange.
In order to better filter your data, you should try to use filter functions when you have nested objects or arrays inside objects and arrays. I had a similar problem in this question: Filtering data with AngularJS Filter. How to iterate over objects?
So, to your question!
First, you need to go one level above to apply the filter to all the objects. Using the filter where you are, you can't see the big picture and act according. The tack by is being used because ng-repeat can't have duplicated values in a array.
<div ng-app='app' ng-controller="MyCtrl">
<div ng-repeat="tweet in tweets | custom track by $index">
for each tweet, user 2's name should be printed here >>
{{ tweet }}
_____________________________________
</div>
</div>
Now, this is the important part. I'm registering a angular.module as app just because I prefer this way. After that, I create a filter called custom that was acessed in the html code.
var app = angular.module('app', []);
I've changed a little your code, So I can see it better in my way:
app.controller('MyCtrl', function ($scope, $timeout){...});
app.filter('custom', function () {
return function (tweets) {
var formatted = []; //Initialize array to be returned.
for (var j = 0; j < tweets.length; j++) { //Iterate over all tweets.
var tweet = tweets[j]; //Select a single tweet.
//Above, iterate over all users on a tweet.
for (var i = 0; i < tweet.users.length; i++) {
var user = tweet.users[i]; //Select a single user of the tweet.
if (tweet.user[i].screen_name == 'user screen name 2'){
//If match what you want, insert it in the array to be returned.
formatted.push(tweet.user[i].name);
};
};
};
return formatted; //Return the array.
};
});
And, finally, if you want to test, here are a fully function jsfiddle with your own code. :)
Query is your string and filter my query like name present in json list
ng-repeat="tweet in tweets" | filter: { users: query }