Question T15011
Visible to All Users

Prevent choicesByUrl to be called if page is not visible or current one

created a year ago

Hello support,
I'm working on a project with this dependencies:

Code
"survey-angular": "1.8.29", "survey-creator": "1.8.29", "survey-knockout": "1.8.29", "survey-pdf": "1.8.29", "surveyjs-widgets": "1.8.29", "survey-core": "1.9.1", "typescript": "~3.2.4"

I can't update to a more recent one, due to heavy customization (for example in that version tagbox didn't work as exptected and we have to implement a fix to it), so that's the first big issue.

The other one is that our solution implies forms with many pages, filled with many dropdowns: surveyjs tries to fill every dropdown of each page right after creating the survey (new Survey.Model( ... blabla... ) and that's how it usually works.

But we need to make the right calls only for those pages that are currently visible, or better, that are the current one, in order to improve the performance: consider that sometimes, when we're are reviewing a form which reached a final state and it's readonly, survey makes 50 to 60 http request, in order to fill ALL the dropdown for all the pages!

As you can see from the picture attached we are viewing the first page ("Tirocinante") but in the network tab you can spot too any HTTP calls make against services which populates dropdowns being visible in other pages as well ("Ospitante", "Tutor" and so on), while the first page has just 5-6 dropdowns.

I managed to find the right point in the code (or at least it's what I think) where I should stop the HTTP call, but somehow I can't prevent it:

Inside my survey.component.ts, inside ngOnInit I inserted these lines of code:

Code
let _this = this; Survey.ChoicesRestfull.onBeforeSendRequest = function (sender: Survey.ChoicesRestfull, options) { let currentPage = _this.utils.dot(sender, 'owner', 'loadingOwner', 'colOwnerValue', 'page', 'survey', 'currentPage'); let senderPage = _this.utils.dot(sender, 'owner', 'loadingOwner', 'colOwnerValue', 'page'); if (currentPage && senderPage && currentPage != senderPage) { options.request.abort(); return; } };

utils.dot is just a custom implementation of the dot syntax of latest versions of TS
I can reach that particular IF but surveyjs is making anyway the calls against the external services.

Is there a way (one at least or the correct one) to do so?

Thanks in advance,
Federico

Comments (1)

    Hello Federico,
    When a survey is loaded, it initializes its elements. At this point, it fetches choices for all questions. A survey may have branching logic or some other functionality which requires survey elements to be ready by the time a survey appears on a page. However, once a survey makes a request and retrieves choices, these choices are cached. With these options, choices are further retrieved from the cache to avoid excessive HTTP requests. The Survey.settings.useCachingForChoicesRestful option is enabled by default in the modern version of a SurveyJS Form Library.
    Unfortunately, it is impossible to somehow cancel choices retrieval - there is no cancellation flag within the sendRequest function of a ChoicesRestful object.
    I may recommend that you check to ensure that choices cache is enabled in your application.

    P.S. Please let me additionally clarify why you are not considering an upgrade? For the record: the modern version of SurveyJS libraries has a TagBox question available out of the box.

    I look forward to your reply.

    Answers

    created a year ago

    Hello Jane and thanks for your response.

    I was able to get the caching available by setting these properties:

    TypeScript
    import * as Survey from "survey-angular"; import * as widgets from "surveyjs-widgets"; import * as surveyCore from "survey-core"; Survey.settings.useCachingForChoicesRestfull = true; surveyCore.settings.useCachingForChoicesRestful = true; surveyCore.settings.useCachingForChoicesRestfull = true;

    Not being sure what was the working one I opted for each one

    But that was not enough, I had to update the json models accordingly, by adding

    Code
    {CACHE}

    at the end of each URL property, i.e. :

    Code
    "url": "/gw/sil-api-pll-altri-servizi/api/altri-servizi/getParametriPLL?parametro=PROVINCE{CACHE}"

    Regarding you P.S.: you do not really want to know who is our customer :-D
    Being seriously: the solution adopted above should really improve the overall performance of the whole user-experience, cause caching is enabled even server side (via Java Spring) but we reach a point of being "too fast" and the microservice working as gateway was not able to face all those concurrent/parallel calls being made by surveyJs model, that's why I asked you how to solve this particular solution.

    Thanks again, I think that the result reached by doing so it's very good!

      Comments (1)

        Hello Federico,
        Thank you for the update and clarification.

        Regarding the settings.useCachingForChoicesRestfull option: as far as I understand, you use the survey-angular package for rendering surveys in your application. If so, a survey data model is available within the survey-angular package. So, it is necessary to import settings from a survey-angular module.

        JavaScript
        import { settings } from "survey-angular"; settings.useCachingForChoicesRestfull = true;

        You're always welcome. Should you have any further questions, please let us know.

        Thanks

        P.S. We hope you enjoyed the level of service you received. If so, we would love if you could leave your feedback on SurveyJS page at g2.com. As we’re building our business, every review helps build credibility for future customers and your feedback would be greatly appreciated.