Why do I get `Call to a member function have_posts() on a non-object `? [closed]

Change

if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post();

to

if ( $the_query->have_posts() ) : while ( $the_query->have_posts() ) : $the_query->the_post();

Why?

When you call $the_query = new WP_Query($query); you’re storing the loop in a variable called $the_query. $query is an array of arguments that you’re passing to the new WP_Query() function. $the_query is a class and have_posts() and the_post() are methods which are basically functions specific to that WP_Query class.