Stefan Wittmann · Jun 7, 2017 go to post

Hi Lucas,

I suggest you open a WRC case with Support so that we can look into the details of what is happening here. This may be a problem specific to the environment.

Regards,

Stefan

Stefan Wittmann · Jan 30, 2017 go to post

Hi Jules,

which Perl distribution are you using? We do support the ActiveState Perl distribution. Also, ensure that you are using a bitness version that matches the bitness of your Caché instance (64-bit in your case).

HTH,

Stefan

Stefan Wittmann · Jan 27, 2017 go to post

Indeed underscore characters are fully supported in the new JSON API (%DynamicObject and %DynamicArray). Are you sure this is the only change you made?

Stefan Wittmann · Jan 16, 2017 go to post

XEP for .NET does support both in-memory and TCP/IP connections. The client must be on the same machine for in-memory connections but can run remotely for TCP/IP connections. Long-term we will move away from in-process connections, but we haven't taken this step yet for XEP for .NET.

We consider support for .NET Core interesting and are currently evaluating support for it. But it is too premature to promise anything yet.

Stefan Wittmann · Nov 14, 2016 go to post

You are correct in your assumption, you have to work with streams to operate on arbitrarely large JSON. %ToJSON and %FromJSON work with streams. Here is an example how streams can work with %FromJSON to read a file:

        set fileStream = ##class(%Stream.FileCharacter).%New()
        $$$THROWONERROR(tsc,fileStream.LinkToFile(<pFile>))
       
        set jsonObject = ##class(%DynamicObject).%FromJSON(fileStream)
Stefan Wittmann · Oct 26, 2016 go to post

Hi Simcha,

you can easily retrieve the data that you are using in your layout (AlerTList in your case), by calling the function getSourceData() on your documentView component. Assuming the id of your documentView is 'mainView', the following code sample should work in your environment:

var view = zen('mainView');

var data = view.getSourceData();

console.log(data.AlerTList);

HTH,

Stefan

Stefan Wittmann · Oct 21, 2016 go to post

We are in the process of updating our Hibernate dialect and plan to push the new dialect to the repository later this year. I got word from our developers that we are using the same strategy as Nicholas provided in his getDefaultMultiTableBulkIdStrategy implementation.

Stefan Wittmann · Oct 4, 2016 go to post

Thanks for sharing!

In case you are looking for an easy way to export SQL data to an Excel file as a developer:  I can recommend SQuirreL as SQL client, which offers Excel and HTML export capabilities.

Stefan Wittmann · Sep 22, 2016 go to post

I agree, Postman is a great tool.

If you want to document your REST interface, take a look at Swagger. You can generate an HTML documentation for your interface and test each call directly. 

Stefan Wittmann · Sep 1, 2016 go to post

As I mentioned before the onevent method is not directly called for most events. The onevent method is only called for viewport changes by default.

Here is an example how you can register your own events. Everything happens in the homepage class.

Step 1) Subscribe to the onPageShow callback

Most pageManagers implement the onPageShow method to let you know when a certain layout has finished rendering. This is a complete documentView example:

<mojo:documentView
 id="mainView"
ongetdata="return zenPage.getContent('data',key,criteria);"
ongetlayout="return zenPage.getContent('layout',key,criteria);"
initialDocumentKey="login"
initialLayoutKey="login"
>
<mojo:jQM-1.4.3-PageManager onPageShow="zenPage.onPageShow(layoutkey,documentkey);">
<mojo:HTML5Helper/>
<mojo:jQM-1.4.3-Helper/>
<mojo:mojoDefaultHelper/>
</mojo:jQM-1.4.3-PageManager>
</mojo:documentView>

Step 2) Implement your logic

I'll just paste the code in here, as I have documented the methods individually:

/// Gets called when a certain layout has been rendered.
/// In this case we are registering additional events and
/// forward them to the onevent callback method in the template.
ClientMethod onPageShow(
    layoutKey,
    documentKey) [ Language = javascript ]
{
    if (layoutKey=='login') {
        zenPage.registerEventHandler('txt-user','keydown');
    }
}

/// Register an event to a layout object by key.
ClientMethod registerEventHandler(
    key,
    eventType) [ Language = javascript ]
{
    var element = zen('mainView').getItemByKey(key);
    element.$findElement('').addEventListener(eventType,new Function('evt','return zenPage.myCustomEventHandler("'+eventType+'","'+key+'");'),false);
}

/// Forward an event to the onevent method in the template.
ClientMethod myCustomEventHandler(
    evtType,
    key) [ Language = javascript ]
{
    var item = zen('mainView').getItemByKey(key);
    var template = zenPage.getTemplate();
    template.onevent(evtType,key,item.$findElement('').value,'mainView');
}

Zen Mojo does not provide a lot of special methods for this task. It involves some coding. 

Stefan Wittmann · Aug 30, 2016 go to post

Herman,

the adaptor approach works for many simple use cases but has issues of its own for more complex scenarios.

If the object graph is huge than the adaptor does a lot of work even if you are only interested in a few properties for some cases.

If you have to serve multiple front-end environments then you have to be able to present an object with multiple levels of details (e.g. native mobile, vs. mobile web vs. desktop web) which require you to do different levels of filtering.

As JSON is more and more used for backend communication as well, you have to be able to produce a verbose JSON output that includes all null values, which are very often omitted for front-ends.

There are many more reasons why you want more control about the projection. We are considering to deliver both approaches: an adaptor class (e.g. %JSON.Adaptor) and a projection method (something like %Compose, but probably with a different name).

Stefan Wittmann · Aug 30, 2016 go to post

Matthew, the system methods (dot-dollar syntax) have been removed in the latest build of the 2016.2 FT. Therefore it is expected that the compiler complains about any .$method you may have in your code.

I am not sure what the issue is with the Macro. Hopefully, Ben can provide more details.

Stefan Wittmann · Aug 29, 2016 go to post

Whether you should be using the default transport layer of Zen and Zen Mojo or built your own REST interface depends on a couple of things:

  1. Your skill set and your development resources
  2. The size of your application
  3. How many different front-end interfaces you have to serve

If you have to serve multiple front-ends, e.g. a native mobile app, a web app and some data to a reporting layer then a REST interface makes you more flexible to actually meet the data needs of each of them without duplicating too much code.

If you just want to get your Zen/Zen Mojo application working without too much extra learning, the standard transport way is just fine.

In general REST interfaces are just a clean way to build your communication layer. If you make your REST calls in the Zen Mojo onGetContent method you will still get the benefits of client-side caching within Zen Mojo. The only real difference is that your data retrieval code now lives in a separate class (a subclass of %CSP.REST) instead of a Zen Mojo template.  

REST interfaces are indeed easier to test and debug as they can be tested by tools. The Zen / Zen Mojo client/server communication requires some knowledge if you really want to know what is going on.

HTH,

Stefan

Stefan Wittmann · Aug 29, 2016 go to post

Hi Ward,

you can contact WRC to get access to the proper 4.x version.

We've made some progress on the npm release, but it will take us more time until we can actually upload the modules to the repository. I will make an announcement here once the node modules are available via npm. 

Stefan Wittmann · Aug 25, 2016 go to post

Steve,

the onevent callback is used for events like viewport adjustments and you should call this method for your custom event handlers.

Zen Mojo does not register to all possible events on a page in order to throw them at onevent. Page performance would be horrible. If you are interested in any additional events, like onkeydown, you have to register them in addition.

HTH,

Stefan

Stefan Wittmann · Aug 22, 2016 go to post

Try passing in the stream object. You are operating on a string, that is why you are getting MAXSTRING errors. This should work:

TRY
{
Set RequestObj = ##class(%Object).$fromJSON(%request.Content)
} CATCH(Exception) {
Set Status=Exception.AsStatus()
}
Stefan Wittmann · Aug 3, 2016 go to post

I am aware of the situation and we are working on publishing the node.js versions via npm independent from Caché kits. While that may take us a while, you can request the latest versions of the node.js module from WRC.

Stefan Wittmann · Jul 28, 2016 go to post

I haven't dealt with SSEs yet, but I can say that WebSockets work like a charm. 

SSEs are not using a special protocol, they work within the HTTP specification and are build on the server by setting the "Content-Type" header to "text/event-stream". From my understanding, this can be easily implemented with a CSP page. 

The reasons why SSEs are not as popular as WebSockets are:

SSEs have some interesting advantages over WS like the use of a simpler protocol, automatic reconnection, and event IDs.

Stefan Wittmann · Jul 19, 2016 go to post

SPAs can work with the browser back and forward button if the URL is updated and the page is pushed to the history stack.  The page Eduard refers to actually mentions this. The jQuery Mobile plugins do implement and support this, you can verify this by opening

/csp/samples/ZMdemo.jQM145.HomePage.cls?

in your browser (point it to your local instance) and play with it.

Currently, our Bootstrap plugin implementation does not support this, because we only implemented a helper plugin and not a page manager. Page managers are responsible for the overall behavior of the SPA.

Stefan Wittmann · Jul 19, 2016 go to post

Hi Fabio,

yes, in theory, there is a way how you can load other templates, but I do not encourage this approach as loading a template can be expensive.

It is better to use one of the following two approaches:

1) Generic utility functions should be placed in a javascript file that can be included

2) You can also build a base template that includes your utility functions and let your other template subclass the base template.

The second approach makes sense if it is unlikely that a given template that requires these utility functions will be loaded and you want to save the footprint. Otherwise, I would always stick to option 1.

Stefan Wittmann · Jul 15, 2016 go to post

I haven't done this before, but I am pretty sure you have to call %Save in order to apply your changes.

Stefan Wittmann · Jul 15, 2016 go to post

As Kyle mentioned your code should be:

<button caption="Save" onselect="zenPage.saveRecord();" />

It appears the section Lisa linked to is not correctly displaying onselect multiple times.

Stefan Wittmann · Jul 12, 2016 go to post

Hi Simcha,

the best way to leverage this widget is to build your own bootstrap dual listbox plugin. Take a look at the code of the other plugins and make sure to check the documentation for creating helper plugins before you start:

http://docs.intersystems.com/latest/csp/docbook/DocBook.UI.Page.cls?KEY…

Let us know if you encounter any difficulties.

N.B.: I should mention that you can also just create the proper HTML code in your layout, but then you have to manually call the initialization and refresh methods in your application code all the time.

Stefan Wittmann · Jul 8, 2016 go to post

The document ID is exposed implicitly as a virtual column named "_documentID". Here is a simple example that you can run in your SAMPLES namespace:

SELECT _documentID, Name, DOB, SSN FROM JSON_TABLE('People','$' %TYPE 'Sample.Document.People')
Stefan Wittmann · Jul 4, 2016 go to post

Kevin, the parser in Atelier should indicate no error here. Updating the Studio parser has a low priority as Atelier is the path forward for the IDE. If you see an issue with Atelier, please let us know. Many thanks.

Stefan Wittmann · Jun 22, 2016 go to post

Yes. The SQL page in the System Management Portal just sends the queries to the Caché server for execution. So every query that is supported by the server will run there.

Stefan Wittmann · Jun 22, 2016 go to post

These two SQL functions are new in Caché 2016.2. Just grab the field test to take a look at them.

I will update the article to include the version, as I have obviously missed this.

Stefan Wittmann · Jun 21, 2016 go to post

Hi Chris,

unfortunately, the information in the Caché Technology Guide that you refer to is outdated. We do support JPA (Java Persistence API) via Hibernate and are currently in the process of updating our dialect. We provide no special tooling for EclipseLink.

I will make sure that the information on the website is updated.