Using Elvis Operator within String Interpolated Expressions in Angular 2 - javascript

In my Angular 2 app I am using string interpolation to pull data from a mongoDB. Right now the server/database in in flux, so on occasion that will break my client-side display because, for instance, if I am pulling in data via string interpolation, like this:
{{record.addresses[0].zipCode}}
... and then, at a later time, the way the data is organized in the database changes, this will break my display - because the client is trying to pull in from fields that are no longer there. So I think I should be able to use something like the elvis operator in a use case like this. That way, if the data is where the client is looking for it, it will print out to the screen. But, if the data is not where it's looking for it, it will just ignore the field altogether - not breaking anything in the display.
So, in short, how would I implement the elvis operator on an expression like I have above?

You use it like this:
{{record?.addresses[0]?.zipCode}}
This will check if record is defined then if addresses[0] is defined under record object and then if zipCode is defined under that object

Related

Is there a way to disable the nested field name feature in react final form?

Please see react final form's docs here
I'm working on a form which obviously is powered by react final form. In the form component, I'm fetching data from an API server and the response body includes something like the following:
{
"configs": {
"name": "abc",
"display.name": "Abc",
"value": 12,
"read.only": true
}
}
As we can see that there are four different key/value pairs in the configs. react final form can display values like name and value just fine but not values like display.name and read.only since they have a dot -> . in their key.
I know I can change these dots (.) with something like underscores and it will work. But the problem is that our backend devs are saying that using dots (.) to separate key names is very common in the backend so replacing dots with other separators won't be an option.
I'm currently replacing these separators with underscores in the frontend but that logic is everywhere and I think there should a better way to solve this. Thanks!
I think the answer is that Final Form just doesn't support keys with dots. Final Form needs some way to know when to go a level deeper into the form values object.
The only solution I could imagine would be to somehow tell Final Form to use another character (similar to how you can choose a different "divider" character when doing search-and-replace in VIM) as the "dot". So you could refer to your display name as <Field name="configs/display.name" delimiter="/"/>, but this feels like a pretty extreme edge case.
Longer term, I'd like to allow providing a type-safe get/set lens for each field, which would also solve this problem.
Wish I had better news for you... 😢
Since you are locked with both a rigid backend naming and Final Form dotkey nested notation, unless you can change one of these two parameters I guess replacing dots with underscore is still the easiest solution.
This is really not about coding itself, as there is basically 3 cases :
Getting rid of Final Form and finding a new one, this could be costy especially if you have multiple devs working on this project. The cost of learning a new syntax, added to the complexity of handling new edge case is not worth it IMO.
Writing a custom view from your backend. You could ask your backend dev to develop a custom viewset for forms so they can keep their dot notation internally. This is usually a bad idea since it could easily create a technical debt, with a side of the dev team not knowing why a particular method exists.
The best is still what you did. Since frontend requires a special response format, it is frontend concern to adapt to what the backend sends, hence creating a custom middleware function that you apply to every incoming responses such as :
const JSONMiddleware = input => (
Object.entries(input).reduce((ac, cv) => {
const newKey = cv[0].replace('.', '_')
ac[newKey] = cv[1]
return ac
}, {})
)
This is probably not optimal in terms of user experience but it is easier to maintain since the problem and its solution are in the same scope of development.

Reference Qualtrics embedded data field containing dot (.) character

When importing fields from a Contacts List, corresponding embedded data fields include dots (.). For example, here's the name of one embedded data that gets automatically created on Contact List import:
result.elements.0.embeddedData.V1
In my survey, I want to access the value stored in this embedded data field. But the getEmbeddedData() javascript method that Qualtrics provides apparently doesn't like dots.
For a simpler example, I shortened the above embedded data name to V.1:
Qualtrics.SurveyEngine.getEmbeddedData('V.1'); // returns null
and a null value is returned.
If I change the embedded data field name to V1 (no .), then the method returns the correct value:
Qualtrics.SurveyEngine.getEmbeddedData('V1'); # returns correct value
In the case where there's a dot in the name, I tried escaping with \\ and \, like: getEmbeddedData('V\\.1'), but both of those escape styles don't work - null is returned.
There is another syntax to access embedded data with javascript - the "${e://Field/myfield}" approach - but I need to be able to set the last character (i.e. the number after V) dynamically, and this method doesn't allow for that. Specifically, for embedded data V1:
var ix = 1;
Qualtrics.SurveyEngine.getEmbeddedData('V'+ix); <-- this works
"${e://Field/V"+ix+"}"; <-- this doesn't work
I have over 1000 fields that get imported from this contact list, so I don't want to rename each one by hand to remove the dots. It seems weird that Qualtrics would pick this naming schema as an import default if it breaks one of its own methods - am I doing something wrong here? Is there an alternate syntax I can use?
I answered your related question on the Qualtrics Community. You can't do "${e://Field/V"+ix+"}" because pipes are resolved on the server before the page is sent to the browser.
When a web service returns json or xml, by default Qualtrics uses a dot for each level in structure. You can override this by changing the embedded variables (on the left in the web service block) to names without dots.
Another alternative would be to write your own web service script that calls the Qualtrics API, then puts the results in a flat json structure before returning them to your survey.
Update based on comments below
Automatically renaming embedded variables returned from a web service call - I think the only way to do that is my alternative suggestion - write your own web service script that converts the info returned from the api and renames the variables putting them in a one dimensional associative array, then convert that array to json.
Qualtrics Question API - getEmbeddedData() has been removed from the documentation. I don't know why, and would have to ask Qualtrics Support. For now, it still works. So, if you need to construct embedded variable names with a dot dynamically, you could create your own function based off getEmbeddedData(). Use your browser's developer tools to see what it does.
I've found addEmbeddedData() to be useless in actual practice. setEmbeddedData() works whether the embedded data field is defined in the survey flow or not. If it is defined in the survey flow, it gets saved to the response data. If it is not defined in the survey flow, it can be referenced throughout the current survey response, but it won't be saved in the response data.

Variables versus template literal interpolation

Are there any cases in which you should use ${foo} in your Apollo query instead of variables: {foo: foo}?
You can do a lot with variables in a GraphQL query!
Obviously, you can pass variables as arguments to various fields
You can also use the #skip and #include directives to modify which fields are in the query
By combining these two tools and possibly others in the future, there's basically no need to do string interpolation.
Why is string interpolation in a GraphQL query bad? Well, for a few reasons it's best to think of a GraphQL query string as a static object, rather than a string to be manipulated:
You could accidentally string-manipulate your way to an invalid query. If you don't properly escape some of the arguments, you could end up with a query that returns an error or some totally different data that you didn't expect. Variables are JSON-encoded, so there's no need to escape them.
If your query is dynamically generated, there's no way to do static analysis on it using tools like eslint-plugin-graphql, so you can't check if your query is valid without actually running your code.
It's going to be more difficult for other developers to understand what the shape of the returned data will be if a query is composed of many different strings. You also can't copy-paste the query into something like GraphiQL to try running it if there is arbitrary JavaScript code in there.
In short, there are tons of opportunities to do cool stuff with GraphQL query strings, but once you start manipulating them with arbitrary code that becomes much more difficult or impossible. So my suggestion is, stick to variables.
TL;DR no, don't use string interpolation in templates. It screws up any static analysis one could do.

Go templating engine that also runs in the browser

I'm developing a web application with Go on the server, and the router will use PushState, so the server will also have to be able to render my templates. That means that I'll need a templating engine that works with Go and Javascript. The only one I've come across so far is Mustache, but it doesn't seem to be able to handle lowercase properties of structs, and there also doesn't seem to be a possibility to provide custom names like JSON:
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
So, is there a templating engine that is available in both Go and JavaScript, and that can handle lowercase struct properties?
As the comments above state, you can't expect any 3rd party library to be able to read lowercase properties on your struct, but it appears you are trying to use tags to represent alternative representations of your struct (as you can with the encoding/json library).
What you can do is use something like github.com/fatih/structs to convert your structs to maps and then range through to lowercase all of your keys (copying the values and removing the uppercase versions) and pass it into mustache.Render() as your context. If you want to use struct tags like the encoding/json library does, you'd have to use the reflect package and write a struct-to-map function that takes into account the tags on the struct (basic example given in the documentation here). There are some SO answers on how to write a struct-to-map function using reflection, which you can improve upon to add struct tag handling as you need.
To answer your question, I don't think this is something a current templating library does that also works with javascript, but it shouldn't be too hard to get working with mustache given the idea above.

Building a SQLite statement in JS and I'm not getting the full command I want

So, I'm building a SQLite statement in JS. The problem is that it appears that %" is turning into "undefined"+ escaping the next character. Here is the exact code:
The part of the sql statement that is messing up is this:
"and s.plainText like '%"+searchText+"%'";
There is more before that, but it all builds correctly. So, in the program if I enter the following as the searchText:
foo
Then when I output the built sql statement to the console, I'm getting the following:
and s.plainText like 'undefinedoo%'
So, it appares that the %" is turning into undefined and causing the first letter of the searchText to be escaped.
How can I build this part of the sql statement correctly? I have to use the " cause the statement contains '. and I have to use the % cause I need the wildcard to seach a string of text.
If by JS you mean JavaScript, then this is not what's happening. Here's the jsfiddle:
http://jsfiddle.net/Ka938/
Try it and you will see it's not a JS problem. The escaping is probably happening later in the process, when this gets to the server or something. Don't know the exact details to help there.
As a guess, if you are using PHP and (s)printf, then sending %f (where f is coming from foo example you used) is going to mean it expects a float - it would display an error, though.
As a side note, it seems that you are sending SQL from the client to the server. If so, it's probably a very bad idea to do this, especially if you are not doing any SQL escaping, as you are not per above. Take a look here:
http://en.wikipedia.org/wiki/SQL_injection
for basic details.
I'm not familiar with webOS, but check this SOq for something that looks to be handling SQL parameters correctly:
in webOS, I need a method that, using the input, will doe a sql select command and returns the restults as an array
Definitively worth doing some more investigation about how to do this properly in webOS - Google is your friend.
The Mojo.Log commands processes the string that you pass a little like the printf function in C. That is you can specify some placeholders that will be filled with the value of the passed parameters. An example is a thousand words so:
Mojo.Log.info("My string is '%s' and my number is '%f'", strData, numData);
will print
My string is 'aaa' and my number is '1'
if strData is 'aaa' and numData is 1.
So most likely your string is built correctly, but printing it will try to replace the %f from %foo% with a parameter. The parameter is never passed so it is undefined. You should see the correct output if you use something else rather than 'foo' to test (try 'bbb').
For more information check out the documentation for Mojo.Log.
PS That being said it's not a good practice to construct your SQL statements like that, so I don't recommend it. Easy to do, but hard to read and maintain later :)

Categories

Resources