I am attempting to map my Core Data "Component" Entity to the "hotspots" keypath in this response JSON, but it only gets to the array object so it will not map. I can't tell if my problem is the mapping or the response descriptor or a combination of the two.
"result" : {
"type" : "Slidedeck",
"id" : 81,
"name" : "Brendantest",
"slides" : [
{
"thumb" : "http:\/\/api.idetailapp.review.thingee.com\/v4\/resources\/1294\/download\/slide?thumb=true",
"id" : 1294,
"notes" : "",
"label" : "",
"order" : 1,
"parent_id" : 81,
"file" : "slide-20.jpg",
"components" : {
"hotspots" : [
{
"x" : 205,
"options" : "embedded",
"type" : "video",
"id" : 6082,
"y" : 453,
"assets" : [
{
"thumb" : "\/system\/asset_objects\/14\/original_thumb\/14.png",
"id" : 14,
"parent_id" : 6082,
"file" : "slide_15_chart_animation_ipad_r03.mov",
"url" : "http:\/\/api.idetailapp.review.thingee.com\/v4\/resources\/14\/download\/asset"
}
],
"parent_id" : 1294,
"width" : 320,
"height" : 246
}
]
},
"url" : "http:\/\/api.idetailapp.review.thingee.com\/v4\/resources\/1294\/download\/slide"
}
],
"version" : "0.43"
}
}
Here is my RKEntityMapping:
RKEntityMapping *mapping = [RKEntityMapping mappingForEntityForName:#"Component"
inManagedObjectStore:[RKManagedObjectStore defaultStore]];
mapping.identificationAttributes = #[ #"componentID" ];
[mapping addAttributeMappingsFromDictionary:#{#"id": #"componentID",
#"parent_id": #"parentID"
}];
[mapping addAttributeMappingsFromArray:#[#"x", #"y", #"width", #"height", #"type", #"options"]];
Here is my Responsedescriptor:
componentResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:componentEntityMapping
method:RKRequestMethodAny pathPattern:nil
keyPath:#"result.slides.components.hotspots" statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
I put in a RestKit/ObjectMapping debug trace and get to the following output:
Asked to map source object (
{
assets = (
{
file = "slide_15_chart_animation_ipad_r03.mov";
id = 14;
"parent_id" = 6082;
thumb = "/system/asset_objects/14/original_thumb/14.png";
url = "http://api.idetailapp.review.thingee.com/v4/resources/14/download/asset";
}
);
height = 246;
id = 6082;
options = embedded;
"parent_id" = 1294;
type = video;
width = 320;
x = 205;
y = 453;
}
And further debug message of:
Failed transformation of value at keyPath 'id' to representation of type 'NSNumber': Error Domain=org.restkit.RKValueTransformers.ErrorDomain Code=3002 "Failed transformation of value '(
6082
)UserInfo=0x12479350 {NSLocalizedDescription=Expected an inputValue of type NSNull, but got a __NSArrayI.}"
),
Your problem is keyPath:#"result.slides.components.hotspots".
Specifically, the fact that slides is an array.
The result is that RestKit is asked to map an array of objects into your mapping. So, when it tries to get the id (which should be a number), it gets an array (hence your error). This is because calling valueForKey: on an array returns an array...
So, basically, you can't do it the way you're trying to because of the array in the middle of the JSON.
If you can get the JSON changed, do that. If you can't, you need to change your mapping to map the slides first and then the nested components (then you can discard the slides afterwards if you want).
Related
My requirement is to create a dynamic resource connector in Kafka cluster. Below is my "connector.tf" file:
resource "confluent_connector" "source" {
environment {
id = confluent_environment.staging.id
}
kafka_cluster {
id = confluent_kafka_cluster.dedicated.id
}
config_sensitive = {
"salesforce.password" : var.source_salesforce_password,
"salesforce.password.token" : var.source_salesforce_password_token,
"salesforce.consumer.key" : var.source_salesforce_consumer_key,
"salesforce.consumer.secret" : var.source_salesforce_consumer_secret
}
config_nonsensitive = {
"connector.class" : "SalesforceCdcSource",
"kafka.auth.mode" : "KAFKA_API_KEY",
"salesforce.cdc.name" : "AccountChangeEvent",
"kafka.api.key" : confluent_api_key.app-manager-kafka-api-key.id,
"kafka.api.secret" : confluent_api_key.app-manager-kafka-api-key.secret,
"salesforce.instance" : var.source_salesforce_url,
"salesforce.username" : var.source_salesforce_username,
for_each = { for s in var.source_salesforce_connector_name : s.source_salesforce_connector_name => s },
"name" : each.value["source_salesforce_connector_name"],
"kafka.topic" : each.value["source_salesforce_topic_name"],
"output.data.format" : each.value["source_salesforce_data_format"],
"tasks.max" : each.value["source_salesforce_max_task"]
}
depends_on = [
confluent_kafka_topic.topic
]
lifecycle {
prevent_destroy = false
}
}
Variable declaration as below: variable.tf file
variable "source_salesforce_connector_name" {
type = list(map(string))
default = [{
"source_salesforce_connector_name" = "SalesforceCdcSourceConnector_0_TF"
}]
}
And I am running this execution from .tfvars file:
source_salesforce_connector_name = [
{
source_salesforce_connector_name = "SalesforceCdcSourceConnector_1_TF"
source_salesforce_topic_name = "json-topic-1"
source_salesforce_data_format = "JSON"
source_salesforce_max_task = "1"
},
]
Getting below error with the execution, please suggest how to pass for_each condition into the JSON configuration as highlighted above.
I tried with above steps and execution, however getting below error:
terraform plan -var-file="DEV/DEV.tfvars"
Error: each.value cannot be used in this context
on modules\confluent_kafka_cluster_dedicated\source_connector_salesforce_cdc.tf line 27, in resource "confluent_connector" "source":
27: "name" : each.value["source_salesforce_connector_name"],
28: "kafka.topic" : each.value["source_salesforce_topic_name"],
29: "output.data.format" : each.value["source_salesforce_data_format"],
30: "tasks.max" : each.value["source_salesforce_max_task"],*
A reference to "each.value" has been used in a context in which it unavailable, such as when
the configuration no longer contains the value in its "for_each" expression. Remove this
reference to each.value in your configuration to work around this error.
If you want multiple confluent_connector resources based on var.source_salesforce_connector_name, then your for_each should be outside of config_nonsensitive:
resource "confluent_connector" "source" {
for_each = { for s in var.source_salesforce_connector_name : s.source_salesforce_connector_name => s },
environment {
id = confluent_environment.staging.id
}
kafka_cluster {
id = confluent_kafka_cluster.dedicated.id
}
config_sensitive = {
"salesforce.password" : var.source_salesforce_password,
"salesforce.password.token" : var.source_salesforce_password_token,
"salesforce.consumer.key" : var.source_salesforce_consumer_key,
"salesforce.consumer.secret" : var.source_salesforce_consumer_secret
}
config_nonsensitive = {
"connector.class" : "SalesforceCdcSource",
"kafka.auth.mode" : "KAFKA_API_KEY",
"salesforce.cdc.name" : "AccountChangeEvent",
"kafka.api.key" : confluent_api_key.app-manager-kafka-api-key.id,
"kafka.api.secret" : confluent_api_key.app-manager-kafka-api-key.secret,
"salesforce.instance" : var.source_salesforce_url,
"salesforce.username" : var.source_salesforce_username,
"name" : each.value["source_salesforce_connector_name"],
"kafka.topic" : each.value["source_salesforce_topic_name"],
"output.data.format" : each.value["source_salesforce_data_format"],
"tasks.max" : each.value["source_salesforce_max_task"]
}
depends_on = [
confluent_kafka_topic.topic
]
lifecycle {
prevent_destroy = false
}
}
I have a czml file representing an aircraft flying a specified path. The file is constructed based on the Sancastle examples provided by Cesiusm (CZML Model + CZML Path).
Here is the CZML variable:
var czml = [{
"id" : "document",
"name" : "CZML Path",
"version" : "1.0",
"clock": {
"interval": "2012-08-04T10:00:00Z/2012-08-04T15:00:00Z",
"currentTime": "2012-08-04T10:00:00Z",
"multiplier": 10
}
}, {
"id" : "path",
"name" : "path with GPS flight data",
"description" : "<p>Hang gliding flight log data from Daniel H. Friedman.<br>Icon created by Larisa Skosyrska from the Noun Project</p>",
"availability" : "2012-08-04T10:00:00Z/2012-08-04T15:00:00Z",
"path" : {
"material" : {
"polylineOutline" : {
"color" : {
"rgba" : [255, 0, 255, 255]
},
"outlineColor" : {
"rgba" : [0, 255, 255, 255]
},
"outlineWidth" : 5
}
},
"width" : 8,
"leadTime" : 10,
"trailTime" : 1000,
"resolution" : 5
},
"model": {
"gltf" : "../../SampleData/models/CesiumAir/Cesium_Air.glb",
"scale" : 2.0,
"minimumPixelSize": 128
},
"position" : {
"epoch" : "2012-08-04T10:00:00Z",
"cartographicDegrees" : [
0,-122.93797,39.50935,1776,
10,-122.93822,39.50918,1773,
20,-122.9385,39.50883,1772,
30,-122.93855,39.50842,1770,
40,-122.93868,39.50792,1770,
50,-122.93877,39.50743,1767,
60,-122.93862,39.50697,1771,
70,-122.93828,39.50648,1765,
80,-122.93818,39.50608,1770,
90,-122.93783,39.5057,1754,
100,-122.93777,39.50513,1732,
110,-122.93793,39.50458,1727,
120,-122.93815,39.50415,1717,
130,-122.9382,39.50362,1713,
140,-122.93818,39.5031,1703,
150,-122.93812,39.50258,1706,
160,-122.93792,39.5022,1707,
170,-122.93775,39.50177,1698,
180,-122.93745,39.50125,1693,
190,-122.93723,39.50073,1694,
200,-122.9373,39.50023,1702
]
}
}];
In order to be able to run the the code I also add the following lines:
var terrainProvider = new Cesium.CesiumTerrainProvider({
url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
requestVertexNormals : true
});
var viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider : terrainProvider,
baseLayerPicker : false
});
viewer.dataSources.add(Cesium.CzmlDataSource.load(czml)).then(function(ds) {
viewer.trackedEntity = ds.entities.getById('path');
});
If you run the code you can see how the center point of the aircraft follows the trajectory, however its heading is not aligned with it thus giving a wrong rap presentation of what the flight should look like:
Would you be able to explain how to add the aircraft orientation to the the code without possible changing the initial czml file structure?
Note: I have found the answer to this question but I was not able to implemented to my problem.
I came up with an answer to the my question. Here there are the lines of codes that if placed in Sandcastle will allow to load the czml file and then add the orientation property through some type of interpolation:
//Sandcastle_Begin
var terrainProvider = new Cesium.CesiumTerrainProvider({
url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles',
requestVertexNormals : true
});
var viewer = new Cesium.Viewer('cesiumContainer', {
terrainProvider : terrainProvider,
baseLayerPicker : false
});
var options = {
camera : viewer.scene.camera,
canvas : viewer.scene.canvas
};
Sandcastle.addToolbarMenu([{
text : 'Lateral avoidance w. real Wx and waypoints (KJFK-LEBL)',
onselect : function() {
viewer.camera.flyHome(0);
viewer.dataSources.add(Cesium.CzmlDataSource.load('./SampleData/interp_turb_data_fromFede_avoid_realistic_w_waypoints.czml')).then(function(ds) {
var entity = ds.entities.getById('path');
// viewer.trackedEntity = entity;
entity.orientation = new Cesium.VelocityOrientationProperty(entity.position);
entity.position.setInterpolationOptions({
interpolationDegree : 1,
interpolationAlgorithm : Cesium.HermitePolynomialApproximation
});
});
}
}], 'toolbar');
Sandcastle.reset = function() {
viewer.dataSources.removeAll();
viewer.clock.clockRange = Cesium.ClockRange.UNBOUNDED;
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK;
};
//Sandcastle_End
In this way the aircraft will be aligned with the trajectory!
I have a list of user's documents in mongodb which is carrying fields like this:
{
"_id" : ObjectId("57fb60caf380e20df0d59f4d"),
"signupFp" : "a47d436a33edb44dfd2c45d6eb5574bd",
"signupIp" : "127.0.0.1",
"password" : "d38c2a8589965d869c79ce77e4dc871e",
"email" : "someemail#gmail.com",
"createTime" : ISODate("2016-10-10T09:35:06.386Z"),
"isAdmin" : false,
"isActive" : true,
"account" : [
{
"port" : 5001,
"server" : "harish server"
},
{
"port" : 7001,
"server" : "harish server"
}
],
"__v" : 0,
"sendEmailTime" : ISODate("2016-10-10T09:35:06.405Z"),
"activeKey" : "61ce67b47ee15547878404d9b5bebab7",
"lastLogin" : ISODate("2016-10-12T07:51:53.059Z"),
"expireTime" : ISODate("2016-10-25T00:00:00.000Z")
}
I am fetching all the user's document using nodejs with the following code:
var User = mongoose.model('User');
User.find({}).exec(function(err, data){
if(err){
return;
}
data.forEach(function(user){
if(user.expireTime < new Date()){
console.log(user.lastLogin); //prints the last login date
console.log(user.account); //outputs []
console.log(user.account.port); //outputs undefined
}
}
}
and further i need value of child nodes i.e account.port and account.server but when i console.log its giving me blank array [] or undefined to console.log a specific child key
How do i get the account.port and account.server values
You have specified var User = mongoose.model('User'); you don't need to do it in the logs anymore (user.lastLogin),(user.account),(user.account.port) just omit the user from all of them, should work.
(lastLogin)
(account)
(account.port)
i'm writing a Play 2.3.2 application using Reactivemongo driver (with Scala).
I've the recommendation.user collection that store all the user data.
One document has the following form:
{
"_id" : ObjectId("542e67e07f724fc2af28ba75"),
"id" : "",
"email" : "luigi#gmail.com",
"tags" : [
{
"tag" : "Paper Goods:Liners - Baking Cups",
"weight" : 2,
"lastInsert" : 1412327492874
},
{
"tag" : "Vegetable:Carrots - Jumbo",
"weight" : 4,
"lastInsert" : 1412597883569
},
{
"tag" : "Paper Goods:Lialberto- Baking Cups",
"weight" : 1,
"lastInsert" : 1412327548205
},
{
"tag" : "Fish:Swordfish Loin Portions",
"weight" : 3,
"lastInsert" : 1412597939124
},
{
"tag" : "Vegetable:Carrots - alberto#gmail.com",
"weight" : 2,
"lastInsert" : 1412597939124
}
]
}
Now i'm writing a method that returns all the tags of a particular user.
I return a JSOn responce.
In play how can i create a dynamic json??
My return json has the following form:
{
"tags": [
{"tag": "tag1"},
{"tag": "tag2"}
]
}
This is my method implementation:
def userTag(user: String) = Action.async {
//obtain all the users saved in the db.
val allUser : Future[Option[User]] = Users.find(Json.obj("email" -> user)).one
val futureComputation = allUser map {
(user: Option[User]) =>
user match {
case Some(x) => x.tags match {
case Some(userTags) => val tags: List[Tag] = userTags.map{tag: (Tag, Double, Long) => tag._1} //obtain all the Tag objects
//here for every element in the tags variable i want to add it add the json.
case None => Ok(Json.obj()) //return an empty json.
}
case None => Ok(Json.obj()) //return an empty json
}
}
futureComputation
}
How can i solve my problem??
Solved using:
def userTag(user: String) = Action.async {
//obtain all the users saved in the db.
val allUser : Future[Option[User]] = Users.find(Json.obj("email" -> user)).one
val futureComputation = allUser map {
(user: Option[User]) =>
user match {
case Some(x) => x.tags match {
case Some(userTags) => val tags = userTags.map{tag: (Tag, Double, Long) => val t = tag._1; t.category + ":" + t.attr} //obtain all the Tag objects
val arrayTags = for(tag <- tags) yield{Json.obj("tag" -> tag)} //crete the array json
Ok(Json.obj("tags" -> arrayTags)) //return the json corresponding to the user.
case None => Ok(Json.obj()) //return an empty json.
}
case None => Ok(Json.obj()) //return an empty json
}
}
//return the Future computation JSON responce.
futureComputation
}
I have an AJAX call inside an ExtJS script, but I'm not sure how to take the returned JSON object and assign it to a variable for use on the page. I'm basically taking a hardcoded extJS script and puting in JSON from database. Here is what I need to do
Get a variable from this AJAX call:
Ext.onReady(function () {
Ext.Ajax.request({
url: '/xxx/clienttool/components/Client-Tool.cfc?method=getResources&returnformat=json',
params: {
accountID: 463
},
success: function(response){
var text = response.responseText;
// process server response here
}
});
and assign it so these values aren't hardcoded:
// Store holding all the resources
resourceStore : Ext.create("Sch.data.ResourceStore", {
model : 'Sch.model.Resource',
data : [
{Id : 'MadMike', Name : 'Mike'},
{Id : 'JakeTheSnake', Name : 'Jake'},
{Id : 'KingFu', Name : 'King'},
{Id : 'BeerBrian', Name : 'Brian'},
{Id : 'LindaAnderson', Name : 'Linda'},
{Id : 'DonJohnson', Name : 'Don'},
{Id : 'KarenJohnson', Name : 'Karen'},
{Id : 'DougHendricks', Name : 'Doug'},
{Id : 'PeterPan', Name : 'Peter'}
]
}),
Here's the whole thing:
Ext.onReady(function () {
App.SchedulerDemo.init();
});
App.SchedulerDemo = {
// Initialize application
init : function () {
Ext.define('Event', {
extend : 'Sch.model.Event',
fields : [
{name : 'Title'},
{name : 'Type'}
]
});
//ajax call to get resources for this accountID
Ext.Ajax.request({
url: '/xxxx/clienttool/components/Client-Tool.cfc?method=getResources&returnformat=json',
params: {
accountID: 463
},
success: function(response){
getResources = response.responseText;
// process server response here
}
});
//alert(getResources);
var zoneStore = Ext.create('Ext.data.JsonStore', {
model : 'Sch.model.Range',
data : [
{
// Nice 2 hour lunch
StartDate : new Date(2011, 11, 9, 12),
EndDate : new Date(2011, 11, 9, 14),
Cls : 'lunch-style'
}
]
});
var sched = Ext.create("Sch.panel.SchedulerGrid", {
height : ExampleDefaults.height,
width : ExampleDefaults.width,
rowHeight : 40,
eventBarTextField : 'Title',
viewPreset : 'hourAndDay',
startDate : new Date(2011, 11, 9, 7),
endDate : new Date(2011, 11, 9, 20),
orientation : 'vertical',
constrainDragToResource : false,
eventBarIconClsField : 'Type',
snapToIncrement : true,
//constrainDragToResource : true,
eventResizeHandles : 'end',
viewConfig : {
// Experimental for CSS3 enabled browsers only
eventAnimations : true
},
// Store holding all the resources
resourceStore : Ext.create("Sch.data.ResourceStore", {
model : 'Sch.model.Resource',
data :
[
{Id : 'MadMike', Name : 'Mike'},
{Id : 'JakeTheSnake', Name : 'Jake'},
{Id : 'KingFu', Name : 'King'},
{Id : 'BeerBrian', Name : 'Brian'},
{Id : 'LindaAnderson', Name : 'Linda'},
{Id : 'DonJohnson', Name : 'Don'},
{Id : 'KarenJohnson', Name : 'Karen'},
{Id : 'DougHendricks', Name : 'Doug'},
{Id : 'PeterPan', Name : 'Peter'}
]
}),
If the only purpose of the AJAX request is to retrieve data for your grid's store, I would ditch it altogether and simply define an AJAX proxy on your store. It will not only accomplish the same initial objective (e.g., getting data for your store), but will also handle creating model instances of your data and binding the store to your grid.
I would suggest checking out the docs for the Store, as well as the grid examples in the documentation.