I am building a simple location tracker in NativeScript. The current location and the past ones are all stored in a view model called scope and constantly updated. When new location data is available, the setter addLocation is called.
var scope = new observableModule.fromObject({
"locations": [],
"lastLocation": {
"latitude": 0,
"longitude": 0,
"altitude": 0,
"horizontalAccuracy": 0,
"verticalAccuracy": 0,
"direction": 0,
"timestamp": "No location yet",
"speed": 0
},
set addLocation(loc) {
console.log('Setter called');
this.lastLocation = loc;
this.locations.push(loc);
}
});
This is imported as view model to the page. The setter is called simply like this:
scope.addLocation = loc;
where loc is the output of watchLocation() from the GeoLocation plugin.
It seems that the setter is not triggered though. The console message never appears. I tried adding other setters, but they also don't work. Getters are working. What is going on?
Related
I have this single type in my strapi dashboard :
I Have a component called Logo
Another component called Links, it contains another component called Link
Finally a component called MenuButton.
When I go to http://localhost:1337/api/global?populate=* I got :
{
"data": {
"id": 1,
"attributes": {
"createdAt": "2021-12-27T11:54:36.177Z",
"updatedAt": "2021-12-27T11:54:54.737Z",
"publishedAt": "2021-12-27T11:54:54.731Z",
"logo": {
"id": 1,
"name": null
},
"navigation": {
"id": 1 // why I don't get links here ?
},
"menuButton": {
"id": 1,
"icon": ""
}
}
},
"meta": {
}
}
I Already published my content and allowed permissions for public.
My question is :
How can I access to the links inside navigation object ?
See my earlier answer here
Strapi 4 requires you to populate your request (see: population documentation )
which could look like this (for level 2 population):
// populate request
const qs = require('qs')
const query = qs.stringify(
{
populate: {
Product: {
populate: ['Image']
}
}
},
{
encodeValuesOnly: true
}
)
// get id
const id = yourId
// get rquest
const Response= await axios.get(
`http://localhost:1337/api/[your api]/${id }/?${query}`
)
Now media links should be included in your response
To retrieve up to 5 levels deep, you can install this package npm i strapi-plugin-populate-deep
I have created a custom edge class as defined here. The only change I made was a No Arg constructor in order to get the import code below to run. I have successfully generated a DirectedMultigraph via the JSONExporter class and now want to take that exported JSON and re-import it via the JSONImporter class.
I'm having trouble doing this and retaining my edge labels due to my limited understanding of how to build the EdgeProvider required for my JSONImporter constructor.
This is the JSON I'm trying to import:
{
"edges": [
{
"id": "{shipmentNumber:12345}",
"source": "DEHAM",
"target": "USNYC"
}
],
"nodes": [
{
"id": "DEHAM"
},
{
"id": "USNYC"
}
],
"creator": "JGraphT JSON Exporter",
"version": "1"
}
This is the code that I have so far:
Graph<String, RelationshipEdge> graph = new DirectedMultigraph<>(SupplierUtil.createStringSupplier(), SupplierUtil.createSupplier(RelationshipEdge.class), false);
VertexProvider<String> vertexProvider = (label, attributes) -> label;
EdgeProvider<String, RelationshipEdge> edgeProvider =
(from, to, label, attributes) -> graph.getEdgeSupplier().get();
JSONImporter<String, RelationshipEdge> importer = new JSONImporter<>(vertexProvider, edgeProvider);
importer.importGraph(graph, new StringReader([inputJSON]);
I know the problem is the EdgeProvider assignment because I don't know how to pass the argument constructor for the RelationshipEdge class which is where the actual label is set. If I could figure out how to call the argument constructor of the RelationshipEdge class then I think that would solve my problem.
FYI, this is my JSONExporter Code:
ComponentNameProvider<String> vertexIdProvider = name -> name;
ComponentNameProvider<RelationshipEdge> edgeLabelProvider = component -> component.getLabel();
ComponentAttributeProvider<String> vertexAttributeProvider = component -> new HashMap<>();
ComponentAttributeProvider<RelationshipEdge> edgeAttributeProvider = component -> new HashMap<>();
GraphExporter<String, RelationshipEdge> jsonExporter = new JSONExporter<>(vertexIdProvider, vertexAttributeProvider, edgeLabelProvider, edgeAttributeProvider);
StringWriter writer = new StringWriter();
jsonExporter.exportGraph(graph, writer);
System.out.println(writer.toString());
The following JSON is exported (with the label/id missing):
{
"creator": "JGraphT JSON Exporter",
"version": "1",
"nodes": [
{
"id": "DEHAM"
},
{
"id": "USNYC"
}
],
"edges": [
{
"source": "DEHAM",
"target": "USNYC"
}
]
}
Since your graph is using the SupplierUtil factory methods, the graph importer will use no-arg constructors as it visits/parses the json file, iterates over all the nodes/edges in the file and creates instances for them. In order to set your node/edge attributes during import you need to provide appropriate Vertex/Edge Attribute Consumers to the importer. Additionally, your node/edge classes need methods to access/modify their attributes:
JSONImporter<String, RelationshipEdge> importer = new JSONImporter<>(vertexProvider, edgeProvider);
importer.addEdgeAttributeConsumer((edgeField, value) -> {
// edgeField: Pair<Edge, String> / Edge instance, field name
// value: instance of org.jgrapht.nio.Attribute / getValue(); getType();
RelationshipEdge = edgeField.getFirst();
e.setLabel(value.getValue()); // Note that since you only have one field I am not finding the
// correct setter. I don't like reflection so I would probably
// add a 'setField(name, value)' method to my edge/node implementation.
});
To persist your graph, the idea is the same. But in this case you need Vertex/Edge AttributeProviders (You added them but they always returned empty maps):
GraphExporter<String, RelationshipEdge> jsonExporter = new JSONExporter<>();
exporter.setEdgeAttributeProvider(e -> {
Map<String, Attribute> attribs = new HashMap<>();
attribs.put("label", new DefaultAttribute<String>(e.getLabel(), AttributeType.STRING));
return attribs;
});
I need to have a third text field besides the Username and Password fields commonly provided by pGina in windows logon UI. I'll be using this field to receive a password to be checked against a one-time password service running in the background.
How can I add the new field in the pGina logon UI and pass its value to a services running in the background?
Any help is appreciated.
I finally managed to to this.
As pointed out by #Alexander, I edited the TileUiLogon.h and TileUiTypes.h and followed the pattern to add a third field to the logon screen.
Then, I edited Credential::Initialize and added a new line in the "for" loop, following the same pattern for the "password" field (I'm not sure exactly what happens there, but since we're complying with the existing pattern, we don't care as long as the content of the new field is collected by the code similar to the other fields).
Since I didn't want to go through changing all the function signatures and mess with the code, I simply edited the Credential::ProcessLoginAttempt function and concatenated the content of the new field with that of the password field and embedded a custom delimiter to allow me separate the two strings in the following steps. After hitting the submit button, the fields data, prior to the real serialization, are initially sent to a pipe on the other end of which the pGina service is listening (pGinaTransactions.cpp). This service sends the login information to its plugins. I then edited the "Sample" plugin already provided and separated the two concatenated strings, immediately filling the password attribute of the object with the real password provided by the user, since these data will be sent back to the credential provider through pipe for further processing. If the plugin returns success, the password is then used for real serialization and logon attempt.
I have probably missed a few details, which you are very welcome to ask in the comments.
I think you must modify TileUiLogon.h file:
namespace pGina
{
namespace CredProv
{
// Fields for unlock and logon:
typedef enum LOGON_UI_FIELD_ID
{
LUIFI_TILEIMAGE = 0,
LUIFI_MOTD = 1,
LUIFI_USERNAME = 2,
LUIFI_PASSWORD = 3,
LUIFI_OTP = 4,
LUIFI_SUBMIT = 5,
LUIFI_STATUS = 6,
LUIFI_NUM_FIELDS = 7,
};
static const UI_FIELDS s_logonFields =
{
LUIFI_NUM_FIELDS, // Number of fields total
LUIFI_PASSWORD, // Field index which submit button should be adjacent to
LUIFI_USERNAME, // Username field index value
LUIFI_PASSWORD, // Password field index value
LUIFI_STATUS, // Status field
{
// when to display, style, field id, type, name data source value callback
{ { CPFS_DISPLAY_IN_BOTH, CPFIS_NONE }, { LUIFI_TILEIMAGE, CPFT_TILE_IMAGE, L"Image" }, SOURCE_NONE, NULL, NULL },
{ { CPFS_DISPLAY_IN_BOTH, CPFIS_NONE }, { LUIFI_MOTD, CPFT_SMALL_TEXT, L"MOTD" }, SOURCE_DYNAMIC, L"pGina", NULL },
{ { CPFS_DISPLAY_IN_SELECTED_TILE, CPFIS_FOCUSED }, { LUIFI_USERNAME, CPFT_EDIT_TEXT, L"Username" }, SOURCE_NONE, NULL, NULL },
{ { CPFS_DISPLAY_IN_SELECTED_TILE, CPFIS_NONE }, { LUIFI_PASSWORD, CPFT_PASSWORD_TEXT, L"Password" }, SOURCE_NONE, NULL, NULL },
{ { CPFS_DISPLAY_IN_SELECTED_TILE, CPFIS_NONE }, { LUIFI_OTP, CPFT_PASSWORD_TEXT, L"OTP" }, SOURCE_NONE, NULL, NULL },
{ { CPFS_DISPLAY_IN_SELECTED_TILE, CPFIS_NONE }, { LUIFI_SUBMIT, CPFT_SUBMIT_BUTTON, L"Submit" }, SOURCE_NONE, NULL, NULL },
{ { CPFS_DISPLAY_IN_BOTH, CPFIS_NONE }, { LUIFI_STATUS, CPFT_SMALL_TEXT, L"Status" }, SOURCE_STATUS, L"Status", NULL },
}
};
}
}
and other related files like pGinaTransactions.h and so on to handle new field. ;-)
As far as i know (if you're on Vista or above), you gonna have to make your own Credential Provider and register it.
For the interaction with the service, i'd say it depends wether it's running in local or on a distant server. Anyway, that's probably the easy part of the work.
UPDATE : I don't know pGina like AT ALL. But you should look at gina.rc (line 93) under DIALOGS. Seems to be an interesting place to begin.
Try to add a custom EDITEXT (by the way, lots of IDE most likely have a visualizor for those resources. I know that Visual Studio is one of them as i already experienced it.)
Visualizor and resource.h --> /!\ This is a screenshot of what it looks like and the resource.h.
//Third TEXTEDIT I just added
EDITTEXT IDC_CUSTOM_PASSWORD_TXT, 146, 88, 183, 12, ES_PASSWORD | ES_AUTOHSCROLL
I'd like to create a Resource Gantt with AnyGantt, currently, when mouse pointer move to the task, it show the resource name and starttime/endtime. I would like to show task name and starttime/endtime.(with following data, I would like to show "task1", not "Equipment#1")
Anyone can help?
Thanks!
[ {"id": 13, "name": "Equipment#1", "periods": [{"id": "task1", "end": 1494099000000, "fill": "green", "start": 1494055800000}]}]
First of all, period's ID is required field and must be unique for gantt chart live edit purposes. You can set any custom field in your raw data like this:
var rawdata = [{
id: 13,
name: "Equipment#1",
periods: [
{
id: "task1",
start: Date.UTC(2017, 4, 6),
end: Date.UTC(2017, 4, 7),
periodCustomName: "Task 1" //This value will be used in tooltip's title.
}
]
}];
Since the data is ready, you have to set custom title format for timeline's tooltip:
//Getting gantt chart's timeline to work with its tooltip.
var timeline = chart.getTimeline();
//Gettnig timeline's tooltip.
var tlTooltip = timeline.tooltip();
//Setting tooltip title format function to access your custom raw data field.
tlTooltip.titleFormat(function() {
//If period is hovered.
if (this.period) {
//Return periodCustomName-field if specified.
return this.period.periodCustomName || this.getData('name');
}
//Else return name of data item ("Equipment#1")
return this.getData('name');
});
I am uploading an image through REST API and getting an answer as below
{
"url": "http://files.parsetfss.com/346a0978-68c7-4d08-a446-62f7422469e7/tfss-8b131ff0-5fd0-4dce-92e8-b7b94da5db9e-pic.jpg",
"name": "tfss-8b131ff0-5fd0-4dce-92e8-b7b94da5db9e-pic.jpg"
}
I want to associate this image to a Promotion object. I also have a Location object which has an array of Promotions. Here is my code:
function promiseToAddPromotionToLocation (locationID, promotion) {
var query = new Parse.Query("Location");
return query.get(locationID).then(function (location) {
var promotionObject = promotionObjectFromJSON(promotion);
location.add("promotions", promotionObject);
return location.save();
}, function (error) {
return Parse.Promise.error(error);
});
}
function promotionObjectFromJSON (promotion) {
var Promotion = Parse.Object.extend("Promotion");
var promotionObject = new Promotion();
if ("message" in promotion) {
promotionObject.set("message", promotion.message);
}
//This causes an error: Uncaught Tried to save an object containing an unsaved file.
if ("photo") {
promotionObject.set("photo", promotion.photo);
}
return promotionObject;
}
When I comment out the part of setting photo, it saves the promotion properly, but when I try to set the file, it gives an error saying Uncaught Tried to save an object containing an unsaved file. How can I solve this problem?
By the way promiseToAddPromotionToLocation is called with the parameters below:
{
"locationID": "fvOiAsoogc",
"promotion":{
"message":"Some text",
"photo":{"name": "tfss-8b131ff0-5fd0-4dce-92e8-b7b94da5db9e-pic.jpg", "__type": "File"}
}
}
The reason was that I was passing the file info without url. Associating file docs show that it only needs name and type. However, this is wrong. It also needs the url. This question in Parse forum reveals it.