Niemożność ustawienia własności obiektu `data` wewnątrz Promise.then() po żądaniu z użyciem axiosa

0
<script>
    export default {
        data: function() {
            return {
                infos: null,
                links: {},
                meta: {},
                url: '/api/info'
            }
        },

        methods: {
            getInfos() {
                axios.get('/api/info')
                  .then((response) => {this.infos = response});
                console.log(this.infos);
            }
        },

        mounted: function() {
            this.getInfos();
        }
    }
</script>

Na końcu this.infos nadal wyświetla się jako null mimo, że usiłuję przypisać mu response. Co ciekawe jeśli wypisze response to dostanę eleganckiego JSON-a.

Gdzie może leżeć przyczyna?

3

Kod promisa jest asynchroniczny, console.log wykona się przed promisem. Mógłbym się rozpisać, ale polecę klasykiem:

0

Wrzucam cały komponent:

<template>
    <section>
        <section>
            <article class="card" v-for="info in infos">
                <div class="card-header">{{info.title}}</div>
                <div class="card-body">{{info.content}}</div>
                <div class="card-footer">{{info.created_at}}</div>
            </article>
        </section>
    </section>
</template>

<script>
    export default {
        data: function() {
            return {
                infos: null,
                links: {},
                meta: {},
                url: '/api/info'
            }
        },

        methods: {
            getInfos() {
                axios.get('/api/info')
                  .then(response => this.infos = response.data.data);
            }
        },

        mounted: function() {
            this.getInfos();
        }
    }
</script>

1

Jesteś pewien, że ten kod Ci się nie crashuje przy v-for? W końcu infos to null.

Spróbuj tak:

<template v-if="infos">
  <article class="card" v-for="info in infos">
    <!-- reszta kodu -->
  </article>
</template>

<template v-else>
  <p>Trwa wczytywanie...</p>
</template>

Btw, mounted: function() { jest tym samym co samo mounted() (ES6) - śmiało korzystaj z tej drugiej składni :-)

0
Patryk27 napisał(a):

Jesteś pewien, że ten kod Ci się nie crashuje przy v-for? W końcu infos to null.

Spróbuj tak:

<template v-if="infos">
  <article class="card" v-for="info in infos">
    <!-- reszta kodu -->
  </article>
</template>

<template v-else>
  <p>Trwa wczytywanie...</p>
</template>

Btw, mounted: function() { jest tym samym co samo mounted() (ES6) - śmiało korzystaj z tej drugiej składni :-)

Zrobiłem tak jak napisałeś, infos jest nullem i takie pozostaje. Nie wiem dlaczego przypisanie nie zastępuje go tablicą obiektów.

2

Kod zdaje się być poprawny, na fejkowych danych działa -> https://codesandbox.io/embed/vue-template-qstxd
Problem leży albo w błędnej ścieżce do danych, błędzie serwera, albo w ogóle poza komponentem.

Btw wrzucaj przypisania w nawias przynajmniej, to raczej nie przyczyna, ale paskudnie wygląda.

0

Z tego co widzę teraz, przypisanie jednak działa, bo dostaję tablicę, jeśli wypisuje wewnątrz .then(), jednak v-for nadal nie wyświetla tego co powinien, nawet jeżeli dodatkowo sprawdzam, czy rozmiar tablicy > 0.

0

Konsola w przeglądarce coś Ci pokazuje?

0

Nie ma błędów, jedynie oczekiwane tablice i informacje, żeby zainstalować sobie Vue devtools i zmienić na production mode później. Próbowałem zwracać dane z PHP w inny sposób, ale efekt ten sam. Wewnątrz .then jest okey, a później tak jakbym tracił te dane, bo na "sztuczne" przypisanie v-for reaguje i wyświetla.

1

Pokaż cały kod. Pobierz sobie Vue Devtools, ten warning nie jest przypadkowy - pomoże Ci pisać aplikacje w Vue, pomoże Ci też prawdopodobnie w tym problemie bo sobie zobaczysz co jest w infos.

0

PHP:

//Laravel: 
//ten kod na podstawie tutoriala, ale zdawał się działać

//Metoda kontrolera: 
public function index()
    {
          $infos = Info::orderBy('id', 'desc')->paginate(10);
          return InfoResource::collection($infos);
    }

//w InfoResource:
public function toArray($request)
    {
        return
        [
            'authorName' => $this->authorName,
            'title' => $this->title,
            'content' => $this->content,
            'created_at' => $this->created_at
        ];
    }

JS:

//Komponent: 
<template>
  <section>
    <article v-if="infos.length > 0">
        <section v-for="info in infos">
            {{info.title}} <!--displays nothing-->
        </section>
    </article>
  </section>
</template>

<script>
export default {
    data() {
       return {
          infos: [],
       }
    },

    mounted() {
        axios.get('/api/info').then(response =>
          {
              console.log(response.data.data);//it outputs array of objects;
              this.infos = response.data.data;//no error;
              console.log(this.infos);//displays similiar array of object with additional
              //properties: observer, reactive getters, setters etc;
          }
        );
    }
}
</script>

<style scoped>
</style>

//app.js
//rejestruję komponent: 
Vue.component('info-list', require('./components/InfoList.vue').default);

const app = new Vue({
    el: '#app',
});


I jeszcze template:

@extends('layouts.app')

@section('content')
<div class="container">
    <div id="app">
        <info-list></info-list>
    </div>
</div>
@endsection 
0

Na sto-pro-i-własną-rękę masz tam w then() funkcję strzałeczkową, tak?

2

Bardzo Wam wszystkim dziękuję za pomoc. Wrzucając tu kod zerknąłem do mojego szablonu a tam w sekcji head:


    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

//Wygenerowane przez framework

//Po czym sam dodałem na końcu sekcji body:

<script src="{{asset('js/app.js')}}"></script>

Po usunięciu linijki z head, v-for wyświetlił tytuły. Problem rzeczywiście okazał się leżeć gdzie indziej niż się spodziewałem, przepraszam, że tak Was zaangażowałem, ale spędziłem przy tym już parę ładnych godzin, tworząc nawet nowy projekt i kilkukrotnie wywołując npm.

1 użytkowników online, w tym zalogowanych: 0, gości: 1