Looping through omdbapi movies array and calling another function

I have renderResult function that loops through array and then calling another function on each element. However, when looping through array I get an error which says movies.forEach is not function.

This is the error I get.

searchView.js:26 Uncaught (in promise) TypeError: movies.forEach is not a function
        at Module.renderResults (searchView.js:26)
        at _callee$ (index.js:56)
        at tryCatch (runtime.js:45)
        at Generator.invoke [as _invoke] (runtime.js:274)
        at Generator.prototype.<computed> [as next] (runtime.js:97)
        at asyncGeneratorStep (index.js:18)
        at _next (index.js:20)

I’ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (’).

where are you using this function renderResults?
you get an error like that if you are passing something that is not an array to renderResults, check the value of the argument you are using when calling that function

Hi, thanks for reply I am new to this forum.
This function receives an array which is movies and I need to loop through the and calling renderMovie on each element.

you are exprting the function and using it somewhere else, right?
the error you get is because somewhere that function is receiving something that is not an array

can you see where you are using that function and check what you are passing to it?

1. {Search: Array(10), totalResults: "28", Response: "True"}

  1. Response: "True"
  2. Search: Array(10)

    1. 0: {Title: "Scarface", Year: "1983", imdbID: "tt0086250", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BNjdjNGQ4ND…jFhZmNlXkEyXkFqcGdeQXVyNjU0OTQ0OTY@._V1_SX300.jpg"}
    2. 1: {Title: "Scarface", Year: "1932", imdbID: "tt0023427", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BOTZiZWIwMm…mIxZjk4XkEyXkFqcGdeQXVyNjUwNzk3NDc@._V1_SX300.jpg"}
    3. 2: {Title: "Lady Scarface", Year: "1941", imdbID: "tt0033805", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BYTlmYWM5Ym…TgzZjU1XkEyXkFqcGdeQXVyNTY4NjI2OTA@._V1_SX300.jpg"}
    4. 3: {Title: "The Scarface Mob", Year: "1959", imdbID: "tt0056449", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BMzNhNTBjYW…2ltYWdlXkEyXkFqcGdeQXVyNDA5ODU0NDg@._V1_SX300.jpg"}
    5. 4: {Title: "Captain Scarface", Year: "1953", imdbID: "tt0045604", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BODZiYzRkNz…zFkZDE0XkEyXkFqcGdeQXVyNzc5MjA3OA@@._V1_SX300.jpg"}
    6. 5: {Title: "Scarface: Origins of a Hip Hop Classic", Year: "2003", imdbID: "tt0395694", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BYzY1MzAwOD…TM2MDE1XkEyXkFqcGdeQXVyMTkwNTc0NDU@._V1_SX300.jpg"}
    7. 6: {Title: "Scarface: Creating", Year: "2003", imdbID: "tt0395750", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BOTM4MDY5Yz…TZjNDkxXkEyXkFqcGdeQXVyMjA3NDg2Mzg@._V1_SX300.jpg"}
    8. 7: {Title: "Scarface: The Rebirth", Year: "2003", imdbID: "tt0395751", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BNTY0MWM4MT…GIxMzYzXkEyXkFqcGdeQXVyMjA3NDg2Mzg@._V1_SX300.jpg"}
    9. 8: {Title: "Scarface: Acting", Year: "2003", imdbID: "tt0395749", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BNzU4N2YwMG…TZhYjQ4XkEyXkFqcGdeQXVyMzE0MjY5ODA@._V1_SX300.jpg"}
    10. 9: {Title: "The Making of 'Scarface'", Year: "1998", imdbID: "tt0432936", Type: "movie", Poster: "https://m.media-amazon.com/images/M/MV5BYjhjYzg4ZT…WQwNWIyXkEyXkFqcGdeQXVyMzE0MjY5ODA@._V1_SX300.jpg"}
    11. length: 10
    12. __proto__: Array(0)

  3. totalResults: "28"
  4. __proto__: Object

I printed the movies array to show its an array that contains an array of movies.

Yes, I am exporting this function to another file.

it’s an object, not an array
to get the array you need to access the Search property of that object

try with

Array.isArray(movies)
Array.isArray(movies.Search)

Array.isArray(movies) returned false
Array.isArray(movies.Search) returned true

Search is an object and then there is an array that returns objects of movies.
I tried accessing the array like : movies.result.Search.forEach(movie => renderMovie(movie)); where the result is property of Search Object class

movies is an object, it has a property called Search that has value of the array you want

you should do movies.Search.forEach(...)

or, instead of changing this function, change the argument where you are calling it.

Here I am accessing the array inside movies object movies.Search.forEach(el => renderMovie(el)); and then I am calling this method like searchView.renderResults(state.search.result); where state is global state of the app and search is the object which lives there and result is the propoerty of search object.
Now, I am showed this error

Uncaught (in promise) TypeError: Failed to execute ‘insertAdjacentElement’ on ‘Element’: parameter 2 is not of type ‘Element’.
at renderMovie (searchView.js:29)
at eval (searchView.js:37)
at Array.forEach ()
at Module.renderResults (searchView.js:36)
at _callee$ (index.js:58)
at tryCatch (runtime.js:45)
at Generator.invoke [as _invoke] (runtime.js:274)
at Generator.prototype. [as next] (runtime.js:97)
at asyncGeneratorStep (index.js:18)
at _next (index.js:20)

You will need to show all your code

It starts to seem an issue with your react code now, and in that I can’t help you

I am not using react its vanilla js code.

This is my Search class.

export default class Search {

constructor(query) {

    this.query = query;

}

async getResults() {

    const apiKey = '#####';

    const proxy = 'https://cors-anywhere.herokuapp.com/';

    try {

        const res = await axios(`${proxy}http://www.omdbapi.com/?apikey=${apiKey}&s=${this.query}&type=movie`);

        this.result = res.data;

        //console.log(this.results);

    } catch (error) {

        alert(error);

    }

}

}

Then in index.js file

where I have state object to keep global state of the app.

const state = {};

const searchControl = async() => {

//1.Get query from searchView
const query = searchView.getInput();

if (query) {

    //2.create search object and add to state
    state.search = new Search(query);

}

//4.search for the user input
await state.search.getResults();

//5.render results or display on UI
searchView.renderResults(state.search.result);

}

You are using template literals for the HTML, so the element is a string. The insertAdjacentElement method expects an actual element (e.g. an element created using createElement).

Use insertAdjacentHTML instead.

OOOHHH. Thanks I didnt see that. I access the object like this movies.Search.forEach(el => renderMovie(el)); and then calling this method like searchView.renderResults(state.search.result);

Just to be clear, I’m talking about in your renderMovie function. The renderResults function calls renderMovie and the html (markUp) inside that function is a string, so you have to use insertAdjacentHTML.

elements.searchResList.insertAdjacentHTML('beforeend', markUp)

Thanks I changed insertAdjacentElement part to insertAdjacentHTML but I am talking about renderResult function when looping we the array movies.Search.forEach(el => renderMovie(el)); and then calling this method like searchView.renderResults(state.search.result);

I don’t know what you are asking, I don’t see a question.

Also, can you please post all the code or better yet a link to a live version on something like CodePen or Repl.it.

Thanks a lot, It seems to be working now with changing movies.Search.forEach(el => renderMovie(el)); and also changing insertAdjacentHTML