0
votes

I am trying to use Nativescript-Carousel plugin to show multiple Google Places. However whenever i set the dataset for Carousel control, i get below exception

System.err: java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 0, found: 20 Pager id: 9 Pager class: class android.support.v4.view.ViewPager Problematic adapter: class com.tns.gen.android.support.v4.view.PagerAdapter_index_222_28_CarouselPagerAdapterClassInner
System.err:     at android.support.v4.view.ViewPager.populate(ViewPager.java:1135)
System.err:     at android.support.v4.view.ViewPager.populate(ViewPager.java:1084)
System.err:     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1614)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at org.nativescript.widgets.CommonLayoutParams.measureChild(CommonLayoutParams.java:262)
System.err:     at org.nativescript.widgets.MeasureHelper.measureChildFixedColumnsAndRows(GridLayout.java:1055)
System.err:     at org.nativescript.widgets.MeasureHelper.measure(GridLayout.java:865)
System.err:     at org.nativescript.widgets.GridLayout.onMeasure(GridLayout.java:279)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at org.nativescript.widgets.CommonLayoutParams.measureChild(CommonLayoutParams.java:262)
System.err:     at org.nativescript.widgets.MeasureHelper.measureChildFixedColumnsAndRows(GridLayout.java:1055)
System.err:     at org.nativescript.widgets.MeasureHelper.measure(GridLayout.java:865)
System.err:     at org.nativescript.widgets.GridLayout.onMeasure(GridLayout.java:279)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at org.nativescript.widgets.CommonLayoutParams.measureChild(CommonLayoutParams.java:262)
System.err:     at org.nativescript.widgets.MeasureHelper.measureChildFixedColumnsAndRows(GridLayout.java:1055)
System.err:     at org.nativescript.widgets.MeasureHelper.measure(GridLayout.java:865)
System.err:     at org.nativescript.widgets.GridLayout.onMeasure(GridLayout.java:279)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at org.nativescript.widgets.CommonLayoutParams.measureChild(CommonLayoutParams.java:262)
System.err:     at org.nativescript.widgets.ContentLayout.onMeasure(ContentLayout.java:32)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
System.err:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
System.err:     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
System.err:     at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
System.err:     at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6083)
System.err:     at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
System.err:     at com.android.internal.policy.DecorView.onMeasure(DecorView.java:689)
System.err:     at android.view.View.measure(View.java:19857)
System.err:     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2275)
System.err:     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1366)
System.err:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1619)
System.err:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
System.err:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
System.err:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
System.err:     at android.view.Choreographer.doCallbacks(Choreographer.java:686)
System.err:     at android.view.Choreographer.doFrame(Choreographer.java:621)
System.err:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
System.err:     at android.os.Handler.handleCallback(Handler.java:751)
System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
System.err:     at android.os.Looper.loop(Looper.java:154)
System.err:     at android.app.ActivityThread.main(ActivityThread.java:6119)
System.err:     at java.lang.reflect.Method.invoke(Native Method)
System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

Here is my code

this.gpsLocationService.getGpsLocation()
            .then((location) => {

                this.latitude = location[0];
                this.longitude = location[1];

                this.nearesthelpService.getNearByPlaces(this.latitude, this.longitude, 5000, 'pharmacy')
                    .subscribe((res) => {
                        this.places = (<any>res).results;
                        console.dir(this.places)
                        let placeDetails: PlaceDetails[] = []
                        this.places.forEach((place) => {
                            this.nearesthelpService.getNearByPlaceDetails(place.reference).subscribe((details: PlaceDetails) => {
                                console.log(details.result.name);
                                placeDetails.push(details);

                                if (placeDetails.length === this.places.length){
                                    this.placeDetails = placeDetails;
                                }
                            })
                        });
                    });
            });

Also here is my template

<GridLayout row="1" *ngIf="placeDetails.length > 0">
        <Carousel #carousel (pageChanged)="onPageChanged($event)">
            <ng-template ngFor let-subitem [ngForOf]="placeDetails">
                <CarouselItem>
                    <GridView rows="auto,*">
                        <Label [text]="placedetail.result?.name"></Label>
                    </GridView>
                </CarouselItem>
            </ng-template>
        </Carousel>
    </GridLayout>

i tried all different ways so that the dataset which is attached to Carousel control is not changed again. As it can be seen above, i also first calculated results in a local object and then attached the same to class variable. However no luck. Any idea why its failing?

Just to add, if i assign the datasource as a static array instead of placedetails, this control does not throw any issue. However when the result is assigned via API result, it does not work.

Just to add, I read on the plugin page that for angular contents can't be changed dynamically. However my requirement is not to change contents once they are received.

1
Can you check if setting the value on pageIndicatorCount helps on your carousel instance. I PR'd the setter for that a few weeks ago, what it does when changed is call the native methods to update the android data adapter so I think this should fix your problem. I also just made a PR to correct the fact the repo has duplicate READMEs and the one on the root of the plugin wasn't being updated, so once merged that will be corrected and documented as seen here github.com/manijak/nativescript-carousel/blob/master/src/… - Brad Martin
@BradMartin It did not help. Just wondering why its failing since its working perfectly fine in another component. Is there is a problem with having multiple instances in same application? - Rajan Phatak
@BradMartin I don't know why someone has downvoted. I have found out the issue but does not have resolution. Issue is occurring since the datasource which is initialised to blank array is assigned with no. of items returned via API i.e. 20. If i assign another static array, it does not thrown any issue. Don't know how to solve this problem. - Rajan Phatak

1 Answers

0
votes

Unfortunately there is no answer to this question. Github page mentions that

(Angular) Only static slides work, the dynamic ones with binding do not (for now).

I was assuming that assigning the data for the first time to an empty array would still be a static slide. However it looks like not the case. If you keep your data ready ahead of time, then you may be able to assign it on initialisation itself.