In all the component classes of each of page of my Angular 2 form, I'm calling an API for retrieval of saved input values to be stored in a global variable in JSON format inside of a global service, if this global variable has not been filled in yet.
After retrieval and initializing the global variable with the JSON data from the API, I'd like to establish 2-way data binding using NgModel on each of my HTML pages with the corresponding values inside this global variable. However, I'm having trouble indexing properly into this global variable containing my JSON data. I'd like to bind my input value directly to the global variable, because upon saving of the form, I can simply call one service that would send this one global variable in the body of a POST call.
JSON Data stored in globalVariable:
How do I retrieve "value a", "value b", "value c" in the HTML?
{
"data": [
{
"field 1" : "value 1",
"page1" : {
"field a" : "value a"
"field b" : "value b"
},
"page2" : {
"field c" : "value c"
}
}
]
}
page1.component.ts:
constructor(..., public globalService: GlobalService:, #Inject(GlobalVariable) private globalVariable: any, ...) {}
ngOnInit() {
if (Object.keys(this.globalService.globalVariable).length < 1) {
this.globalService.getAPI().subscribe(
data => this.globalService.globalVariable = data['data'],
err => console.error(err),
() => {
console.log(this.globalService.globalVariable[0]['page1']['field a']); //Prints 'value a' correctly!
//In HTML:NgModel: I can't index globalVariable[0]['page1']['field a']
//this._privateVariable = this.globalService.globalVariable;
//In HTML:NgModel: I can't index _privateVariable[0]['page1']['field a']
//this._privateVariable = this.saveInformation.information[0]['page1'];
//In HTML:NgModel: I can index _privateVariable['field a'] for ['value a'], but //I don't want to manage many _privateVariables, each storing each page's input
//values to be sent in POST request in save.
}
)
}
}
page1.component.html:
...
<div>
<input type="text" [(ngModel)]="globalVariable[0]['page1']['field a']">
</div>
...
The above line outputs the following error to console:
angular2.dev.js:25644 ORIGINAL EXCEPTION: TypeError: Cannot read property '0' of undefined
There are mistake in your code while fetching data and using in the view (HTML). you have to use code like this :-
<input type="text" [(ngModel)]="globalVariable.data[0].page1['field a']">
also
PS: There is space between your name of key i.e field a so to access the value of JSON object key having space you have to use bracket notation of javascript.
see here working demo of your use case
Working Example
see also
https://medium.com/#prufrock123/js-dot-notation-vs-bracket-notation-797c4e34f01d#.ytvne8m86
Related
A JSON string string passes the jsonlint test.
response = [
{
"article" : {
"info" : {
"initial" : {
"articleIds" : [
"7461221587662919569"
],
}
},
"text" : "where they would 'transfer to' next.",
"lang" : "en",
}
},
{
"article" : {
"info" : {
"initial" : {
"articleIds" : [
"6613144915874808065"
],
}
},
"text" : "produto regional.",
"lang" : "pt"
}
}
]
However, after processing
require 'json'
file = File.read('/Users/main/jugg//article_samples.js')
data_hash = JSON.parse(file)
One is left with an array, whereas more frequently a hash with a name labels a subsequent array, where one works with that nomenclature such as response['data']
But in this case the array is not accessible via response[0]. How can this be considered as an array in order to process each individual element collection.each do |member|?
A curiosity: data_hash.class => NilClass
The response = ... code from article_samples.js is JavaScript, not JSON. This initializes a variable named response with a JavaScript array.
To use this as JSON, then rename the file to article_samples.json and remove response = from the file. The first line should start with [.
Now your second block of code should work just fine as long as the article_samples.json file is in the correct path.
On a side note, I suggest that you find a way to make the path more flexible. The way you have it currently hard coded is tied directly to your current machine's file system. This won't work if you want to run this code from another machine because the folder /Users/main/jugg probalby won't exist.
If this is a web server with ruby on rails, then one solution is to create an environment variable with the path where this file is stored.
I want to create a global variable from json data. I'm sending the json data with websockets from a server to a client and I want that when the client receives json data, it creates a global variables for further use.
My json data is:
set_variable_data = [{
'component' : {
'name' : input("Component name: "),
'evse' : {
'id' : int(input("Number of Evses: ")),
'connector_id' : int(input("Number of connectors: "))
}
},
'variable' : {
'name' : input("Variable name: ")
}
}]
And I've tried to implement this code into the client program:
global set_variable_data[0]['variable']['name'] = set_variable_data[0]['component']['evse']['connector_id']
There's no problem with the send/receive procedures, all the messages are sent and received between the client and the server. I just want to know if we can create a global variable from this.
Thanks in advance
You can use the global keyword to modify a global variable from inside the function thar receives the data:
variable_data = {}
def receive_data(interface):
global variable_data
variable_data = interface.recv_json()
The global keyword allows to reference the variable variable_data when is assigned a value to it, in other case you will be making the assignation to a variable only inside the context of the function.
I have orchestrated a data pipe line using AWS Step function.
In last state I want to send a custom notification. I'm using an Intrinsic function States.Format to format my message and subject. It works fine for Context object element. Here, I have tested that in Message parameter.
But it doesn't work with input JSON. This is my input JSON
{
"job-param":{
"pipe-line-name":"My pipe line name", "other-keys":"other values"
}
}
"Success State": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"Message.$": "States.Format('Execution Id:{}, completed successfully!', $$.Execution.Id)",
"Subject.$": "States.Format('[INFO] {} completed successfully!', $.job-param.pipe-line-name)",
"TopicArn": "arn:aws:sns:us-east-1:************:sns-topic"
},
"End": true
}
While saving this state machine, it gives me following error message:
The value for the field 'Subject.$' must be a valid JSON Path
I checked Input and Result path. They have this value. I can directly use this value as parameter. This is working fine. But I can't format with other string.
"Subject.$": "$.job-param.pipe-line-name"
Alternate approach would be to call lambda to customize and trigger SNS. But I want to avoid that.
Can I request some suggestions to fix this error?
Thanks in advance!
If you want to use any name with - in your JSON then you can write your JSON Path like this:
"Subject.$": "States.Format('[INFO] {} completed successfully!', $['job-param']['pipe-line-name'])",
But it would be easier if you change your input JSON and replace - with _:
"Subject.$": "States.Format('[INFO] {} completed successfully!', $.job_param.pipe_line_name)",
I'm trying to get each of of the values inside my JSON file but when I run my API I get [Object Object] instead of what is inside the JSON.
This is my API request:
getAllvalues(): Observable<string[]> {
return this.http
.get<string[]>(this.Url + 'api');
}
my component.ts
this.ddvService.getAllvalues()
.subscribe(response => {
this.slots = response;
console.log (this.slots)
});
Example of my JSON response:
[
{
"AB": "http:"
},
{
"DE": "http:"
},
{
"CE": "http:"
},
{
"HI": "http:"
}
]
How can I get the value inside the JSON, and create a dropdown box with each of them?
Your example JSON is a pretty bad example: each object in the array in the JSON should have at least somewhat matching key names. In your case, the keys are "AB", "DE", "CE", "HI" - all different, which is quite uncommon in real-life. A more realistic JSON response would have matching key names, e.g.:
[
{
"id": "1",
"description": "Some description"
},
{
"id": "2",
"description": "Another description"
}
]
Now to answer your questions:
You are getting [Object Object] because you are trying to use an entire object as a literal value. Instead, you should access the individual keys/values of an object. For example: console.log(slots[0].id) - this should output 1.
Also, as indicated in the comments, replace Observable<string[]> with Observable<any[]> and get<string[]> with get<any[]>.
To create a drop-down in Angular, in your component template you can try this, assuming your slots value is the JSON above:
<select *ngIf="slots" name="slots">
<option *ngFor="let slot of slots" value="slot.id">{{ slot.description }}</option>
</select>
Also, to print the entire object to console in a readable form, instead of just console.log(this.slots);, you can try console.log(JSON.stringify(this.slots));
As mentioned in the comments above it is not ideal to have json like you have, my assumption is you might want to log keys instead of values, since value is same for all the objects in array. In that case you might want to try something like this.
1. Add any[] instead string[].
2.Add nested for loop to console.log your object array.
getAllvalues(): Observable<string[]> {
return this.http
.get<any[]>(this.Url + 'api');
}
this.ddvService.getAllvalues()
.subscribe(response => {
this.slots = response;
for(let i in this.slots)
{
let currentObj = this.slots[i]; // example of first in array { AB : "http:"}
for ( let z in currentObj )
{
if(currentObj[z]=== "http:") // we are trying to find key instead value
{
console.log(z); // it will log AB, DE, CE, HI ..
}
}
}
});
Assuming one were to post multiple data sets of one model at the time through JSON, it is possible to insert these using Eloquent's Model::create() function. However in my case I'll also need to validate this data.
The Validator only takes a Request object as input, and as far as I've seen I can't create a new Request instance with only one model.
Assuming this would be the input data (JSON), and index is the value for the browser to know what data belongs to an what item (as they have no unique ID assigned at the point of creation)
[
{
"index" : 1,
"name" : "Item 1",
"value" : "Some description"
},
{
"index" : 2,
"name" : "Item 2",
"value" : "Something to describe item 2"
},
(and so on)
]
Every object in the root array needs to be ran through the same validator. The rules of it are defined in Model::$rules (public static array).
Would there be a way to run the validator against every item, and possibly capture the errors per item?
You can utilize Validator for manual validation:
...
use Validator;
...
$validator = Validator::make(
json_decode($data, true), // where $data contains your JSON data string
[
// List your rules here using wildcard syntax.
'*.index' => 'required|integer',
'*.name' => 'required|min:2',
...
],
[
// Array of messages for validation errors.
...
],
[
// Array of attribute titles for validation errors.
...
]
);
if ($validator->fails()) {
// Validation failed.
// $validator->errors() will return MessageBag with what went wrong.
...
}
You can read more about validating arrays here.