Troubleshooting promise failure: Unable to display data in template

I have been experimenting with various approaches to create and return a RSVP.Promise as a parameter for my template.

All console.log outputs reasonable values, indicating that the promises are indeed resolving. The issue I am facing (which then becomes the question) is how to effectively pass these resolved values to my template.

Below are the different versions I have attempted:

// in controller.js
testA: Ember.computed('sessionAccount.account.id', function() {
    let _this = this;
    let promise = new Ember.RSVP.Promise(function(resolve, reject) {
        _this.get('store').findAll('accounts2workgroup').then(function(a2ws) {
            let workgroups = [];
            a2ws.forEach(function(a2w){
                if(a2w.get('rights')>1) {
                    workgroups.push(a2w.get('workgroup'));
                }
            });
            console.log(workgroups);
            _this.set('wgAsAdmin', workgroups); // this works
            resolve(Ember.A(workgroups));  //=> [Object] in rendered template
            // return workgroups; // no, not that way
        });
    });

    promise.then(function(data) {
        console.log('did resolve');
        console.log(data);
    })

    return promise; 
}).property('sessionAccount.account.id'),

testB: Ember.computed('sessionAccount.account.id', function() {
    return new Ember.RSVP.Promise(function(resolve, reject) {
    let workgroups = Ember.ArrayProxy.create([{'label': 'TestB Label'}]);
        resolve(workgroups);

    });
}),

testC: Ember.computed(function() {
    return this.store.findAll('artists2workgroup').then(function(a2ws) {
            let workgroups = [];
            a2ws.forEach(function(a2w){
                if(a2w.get('rights')>1) {
                    workgroups.push(a2w.get('workgroup'));
                }
            });
            console.log(workgroups);
            return workgroups; //=> [Object] in rendered
    });
}),

testD: Ember.computed(function() {
    return this.store.findAll('workgroup'); 
}),

Within my template, I test all my functions as follows:

<h4>TestB</h4>
{{#each testB as |wg|}}
        {{wg}}<br>
        {{wg.label}}<br>
{{/each}}
testB: {{testB}}<br>
testB.length: {{testB.length}}<br>

and all (except for the last testD) render like this:

TestB
testB: [object Object]
testB.length:

whereas I expect/want them to display like this:

TestB
<DS.PromiseObject:ember1117>
BB-Promotion
testB: <DS.PromiseObject:ember1117>
testB.length: 1

I acknowledge there are alternative solutions to this (such as setting another property upon resolving), but I prefer to accomplish it correctly and understand the process thoroughly. I am aware that these examples may seem simplistic. This is just the initial functionality, which will be expanded once I achieve successful implementation.

Answer №1

To start off, it's best to steer clear of the explicit promise construction antipattern. Additionally, there's no need to store 'this' because arrow functions in ember-cli eliminate that requirement. Let's revise your 'testA' function:

testA: Ember.computed('sessionAccount.account.id', function() {
    return this.get('store').findAll('accounts2workgroup').then(a2ws => {
        return workgroups
            .filter(a2w => a2w.get('rights') > 1)
            .map(a2w => a2w.get('workgroup'))
    });
}).property('sessionAccount.account.id'),

The above code won't work as expected. The issue here is that ember templates do not handle promises properly. There are three options available to tackle this problem:

  1. Avoid using this approach altogether. Often, async tasks can be handled in the routes 'model' hook.
  2. Consider utilizing tools like 'ember-promise-helpers' within the template.
  3. Avoid returning just a Promise.

If option 1 is not suitable for your situation, I suggest going with option 3. This involves understanding the PromiseProxyMixin. In ember-data, you have two implementations of this Mixin - PromiseArray and PromiseObject.

All ember-data methods such as findAll, findRecord, query, or async relationships return either a PromiseObject or a PromiseArray. They act as both a promise and a regular object. The promise part is beneficial in the routes 'model' hook, while the Object/Array aspect is useful for computed properties. An easier way to proceed would be to split your CP into two sections:

allWorkgroups: Ember.computed(function() {
    return this.get('store').findAll('accounts2workgroup');
}),
testA: Ember.computed('sessionAccount.account.id', function() {
    return this.get('allWorkgroups')
        .filter(a2w => a2w.get('rights') > 1)
        .map(a2w => a2w.get('workgroup'))
}).property('sessionAccount.account.id'),

This setup will work effectively, updating the array when the promise resolves and recomputing the testA CP.

Alternatively, you can manually create a new PromiseArray:

testA: Ember.computed('sessionAccount.account.id', function() {
    const promise = this.get('store').findAll('accounts2workgroup').then(a2ws => {
        return workgroups
            .filter(a2w => a2w.get('rights') > 1)
            .map(a2w => a2w.get('workgroup'))
    });

    return DS.PromiseArray.create({promise});
}).property('sessionAccount.account.id'),

It's important to note that in both cases, there won't be any indication if the Promise fails!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

One way to add a JSON object to an empty JSON array using Javascript involves pushing

Currently, I am facing an issue with an empty JSON array. shoppingCart: [] In addition to the empty array, I also have a JSON object defined as follows: let product = {"name": "name", "price": "price", "quantity": "quantity", "logoPath": "logoPath"}; M ...

Retrieving the output from within an AJAX function

I am trying to access the return value of the "res" variable from the function but it returns undefined. How can I solve this issue? function getResult() { var url = "https://translate.yandex.net/api/v1.5/tr.json/translate", keyAPI = "abcdefgh" ...

Oops! RangeError [MESSAGE_CONTENT_TYPE]: The content of the message must be a string that contains at least one character

Can someone help me troubleshoot my regular send command? I keep encountering an error message even after following suggestions from previous answers. Here is the error: RangeError [MESSAGE_CONTENT_TYPE]: Message content must be a non-empty string. at ...

Unable to pass an event parameter using my this.handleChange function in react-native

Encountering an issue with the error message "undefined is not an object (evaluating 'event.preventDefault)" It appears that I am unable to pass an event parameter to the handleChange function in my child component, which is being rendered in the par ...

Exploring protractor and webdriver basics in the context of a non-angular application

Currently, I am in the process of writing end-to-end tests for a non-angular application using Protractor. While there is a wealth of information available on how to achieve this, it appears that there are multiple approaches to consider. This has led me ...

Puppeteer failing to detect dialog boxes

I'm attempting to simulate an alert box with Puppeteer for testing purposes: message = ''; await page.goto('http://localhost:8080/', { waitUntil: 'networkidle2' }); await page.$eval('#value&apos ...

Steps to include a catch statement to resolve Unhandled promise rejection alert

I am currently working on implementing user authentication for my website. The registration route is functioning perfectly, but I seem to encounter an Unhandled promise rejection warning when attempting to make a request to the login route. I have attempt ...

Is there a way to determine if a visitor has returned to my website using the browser's back button?

As a newcomer to javascript, I am looking to implement some functionality using javascript. Specifically, I am interested in redirecting users who arrive at my site via the browser back button. I have come across several solutions that work for existing ...

Wait for another user keypress event in jQuery after a 0.5 second delay

Currently, I am working on developing a live search feature for my website. In order to reduce unnecessary requests and optimize performance, I am looking to implement a simple jQuery solution (while also ensuring that there is back-end flood control in pl ...

What is the best way to set the v-model property to an object that is constantly changing

I'm in the process of creating a dynamic form that allows users to add additional fields by simply clicking on a button labeled "adicionar condição." The concept is similar to what can be seen in the screenshot below: https://i.stack.imgur.com/Mpmr6 ...

Display the file name of the following/preceding images on the backward/forward button

Hello, I am fairly new to web development and could use some professional assistance. I have a slideshow set up, but I am struggling with adding the filename of the next or previous images to the back/forward icons of the slideshow. Is this achievable with ...

Hearken to a Vue event using regular JavaScript

One of my Vue components emits the change event. methods: { onSelect(value) { this.open = false if (value === this.value) return this.$emit('change', value) }, } I have integrated this component into an .astro file ...

When attempting to delete an item from Firebase using React, the re-render results in the item being

I'm currently in the process of developing an app to enhance my React skills, and I've chosen Firebase for data storage. Everything seems to be working fine as all items from Firebase are rendering properly. However, I've encountered an issu ...

Trouble updating Express-Session cookie

Hello, I have been working with express.js and have encountered an issue with express-sessions. Here is how my express session is configured in index.js: app.use( session({ secret: 'idegas', resave: false, saveUninitialized: false, cook ...

Having issues with the forEach and map functions not iterating through every item in an async-await function in Vue.js?

My orders array contains a number of meal plans, each with items inside. I'm trying to process all orders as paid in the inner loop when I click on place orders. However, the code is only processing some and leaving others behind. Below is my implem ...

What are the reasons and situations where it is beneficial to utilize the input type

Could someone provide an explanation on this subject, detailing its purpose and how it should be understood? <input type="hidden" name="msg" value="GATEFORUM|OE180187|NA|0.00|NA|NA|NA|INR|NA|R|gateforum|NA|NA|F|AMIT SINGH|9993523486|gis16|NA|NA|NA|NA ...

Troubleshooting a Laravel method invoked in JavaScript using PhpStorm

I'm seeking some advice on how to debug a Laravel function mapped in a JavaScript function that is being called in an HTML page. $('#upload-avatar').fileapi({ url: '{{ route("user.avatar") }}', accept: 'image/*&a ...

Utilizing the HasMany - BelongsTo relationship in Ember.js with the RESTAdapter

Can anyone provide guidance on creating a has many belongs to relationship using RESTAdapter in EmberCLI? I am working on a project where a card (representing a Twitter user) can have multiple hashtags associated with it. Here are my model definitions: / ...

Present pop-up messages in the most sophisticated manner

I have successfully created an AngularJS app that is functioning well. Now, I am faced with the challenge of displaying different pop-ups based on specific conditions being met. I am unsure of the best approach to take. Currently, I am considering two op ...

Leveraging jQuery to establish headers in an ajax request

I want to integrate an Office 365 Rest API into my application. When I test the URL within the same browser session, I can view some XML data. https://i.sstatic.net/1lbZZ.png However, when I try pasting the URL into an incognito window, I encounter this ...