0

i call for the api to fetch data, i test it with postman and laravel send it as an array correctly, but vue turn my array into [ob: Observer] and i cant extract my array from it thanks to @Stockafisso it has been solved but

Edit: now my problem is, programming_languages array is only accesible inside getLanguages() method not anywhere else

 data(){
        return{
             answer: '',
             maxWrong: '',
            programming_languages : []              
        }
    },

    methods:{

        getLanguages(){
            axios.get('/api/toController').then((response)=> { 
  this.programming_languages = JSON.parse(JSON.stringify(response.data)); //works fine

this.answer = this.programming_languages[Math.floor(Math.random() * this.programming_languages.length)].name; //works fine
          this.maxWrong = this.answer.length;// works fine here, i dont want to initiaize answer variable in this method
                  
        
            });
        },

randWord(){
        this.answer = this.programming_languages[Math.floor(Math.random() * this.programming_languages.length)].name;// it is not working here
//Error in created hook: "TypeError: Cannot read property 'name' of undefined"
            this.maxWrong = this.answer.length;// doesn't work here
          
        }

    },
    created(){
           this.getLanguages();
           this.randWord();
    }

what can i do? thank you

Ramin Safari
  • 19
  • 2
  • 9
  • Can you show us the api response? – Hamid Ali Jun 28 '20 at 08:38
  • return ModelName::all(); it sends a nested array, i tested it by postman, that was correct, and i can also see the array inside [ob: Observer] when i use JSON.parse(JSON.stringify(response.data), but i cant extract it into array – Ramin Safari Jun 28 '20 at 08:51

2 Answers2

0

most probable the error(s) is here: this.programming_languages.push(JSON.parse(JSON.stringify(response.data)));

you are inserting the Laravel returned array inside the declared programming_languages, while you should override or concat it. To explain better, a little example:

consider this:

let arr1 = [];
let arr2 = [1,2,3];

if you do arr1.push(arr2) your arr1 will be [[1,2,3]] while you want it to be [1,2,3].

Going back to your problem, to fix it you have two ways:

a)

.then((response)=> { 
                 this.programming_languages = JSON.parse(JSON.stringify(response.data));

b)

.then((response)=> { 
let swapArray = [...this.programming_languages];
this.programming_languages = swapArray.concat(JSON.parse(JSON.stringify(response.data)));

If this does not fix the error, it could be the problem is in the array returned from Laravel. If it has not numeric or not sorted keys, JS will "fill" the missing spaces with Ob. Observer to try to keep the keys.

Raffobaffo
  • 2,806
  • 9
  • 22
  • thanks for your rely @Stockafisso, actually it is a nested array containing string and numeral value which are generated from database, when i popluate programming_languages array manually there is no error, i can easily for example console.log(this.programming_languages[0].columnName)) but when i fetch it from database i cant extract array and set it into array, [__ob__: Observer] is in the way – Ramin Safari Jun 28 '20 at 08:03
  • by the way nested array is ordered based on id(database primary key) and [__ob__: Observer] works fine with – Ramin Safari Jun 28 '20 at 08:23
  • Hi Ramin, Still, also if is a nested array, you should concat it and not push. To see if I'm correct, just try to do `this.programming_languages[0][0].name` – Raffobaffo Jun 28 '20 at 08:51
  • hi Stockafisso, thank you so much it works like a charm when i console.log(this.programming_languages[0][0].name); but when i this.answer = this.programming_languages[0][0].name; it throws an error TypeError: Cannot read property 'name' of undefined", name is a column in database, i want to

    {{ answer }}

    – Ramin Safari Jun 28 '20 at 09:02
  • Hi @RaminSafari, great. This means that my solution is correct. Instead of using [0][0], just use one of the two solutions I posted (a,b), and you will be able to access the objects in the array. Regarding the `this.answer = this.programming_languages[0][0].name;` thats seem more a problem of when actually you do this request, it could be the array is not yet instantiated. Please also accept my answer as the correct one :) – Raffobaffo Jun 28 '20 at 09:06
  • dear Stockafisso i got the result with this.programming_languages.push(JSON.parse(JSON.stringify(response.data))); not by that 2 methods you mention but alot of thanks because i can extract the array with the way you said this.programming_languages[0][0].name; i am stucked in type error, in fact when i use the programming_language[0][0].name in another method(other than getLanguages) it throws tyoe error and also Cannot read property '0' of undefined – Ramin Safari Jun 28 '20 at 09:28
  • Hi, this line `this.programming_languages.push(JSON.parse(JSON.stringify(response.data)))` is wrong. As said, use one of the two methods I posted up here in my solution, else you won't get it working. By the way, you should also check why you are JSON encoding and decoding the values in the same line, that is most probably not needed there. – Raffobaffo Jun 28 '20 at 09:31
  • stockafisso thanks for your persistence, i tried both ways again and again but didn't work but push method works fine, i can easily use this.programming_languages[0][0].anyColumn, but when i write down this very line of code in another methods it throws an error Cannot read property '0' of undefined – Ramin Safari Jun 28 '20 at 09:39
  • If you use one of my proposed methods, you should not use [0][0] to access the content of the first element in the array, but [0] instead. – Raffobaffo Jun 28 '20 at 09:43
  • hi Stockafisso, you are right, i can use console.log(this.programming_languages[1].name); when approach u said, but i can't use this valid code inside another method, "TypeError: Cannot read property 'name' of undefined" – Ramin Safari Jun 28 '20 at 10:22
  • randWord(){ console.log(this.programming_languages[Math.floor(Math.random() * this.programming_languages.length)].name); } i get error Error in created hook: "TypeError: Cannot read property 'name' of undefined", but if i console it inside getLanguages() it works fine – Ramin Safari Jun 28 '20 at 11:44
0

thank you all, finally i managed to solve it

first i extract array from vue's [ob: Observer]

this.programming_languages = JSON.parse(JSON.stringify(response.data));

special thanks to @stockafisso

and second was that i couldn't get this programming_languages array out of axios method, that happens due to nature of asynchronous call, see this informative link

How do I return the response from an asynchronous call?

i managed to solve it this way, async and await

methods: {

 async getPosts(){
           
          await axios.get('/api/hangman').then(response => {
                   this.programming_languages =  JSON.parse(JSON.stringify(response.data));
             
            }).catch(error => console.log(error));
        },
        
        randWord(){
            
        this.answer = this.programming_languages[Math.floor(Math.random() * this.programming_languages.length)].name;
        this.maxWrong = this.answer.length;
        },
},

 created(){
            
          this.getPosts().then(() => this.randWord());
                                
      }
Ramin Safari
  • 19
  • 2
  • 9